From fd8284b51cd029be03e02c5b419ce3f3c096af6d Mon Sep 17 00:00:00 2001
From: nbv <nbv@opencascade.com>
Date: Wed, 18 Jan 2017 12:18:24 +0300
Subject: [PATCH] 0028211: Modeling Algorithms - Boolean fuse operation
 produces incorrect result

The reason of the regression is a mistake while classification of some face (created by Boolean algorithm and looks like thin ring) as hole. In the fix, another algorithm for classification is used.

Additional corrections:

1. Classes IntTools_FClass2d and BRepTopAdaptor_FClass2d have been joined to the single class BRepTopAdaptor_FClass2d (IntTools_FClass2d has been eliminated but now, BRepTopAdaptor_FClass2d is configured as current version of IntTools_FClass2d).

2. Interface (and algorithms) of following classes have been changed: BRepClass3d_Intersector3d, BRepClass_FClass2dOfFClassifier, BRepClass_FClassifier, BRepClass_FaceClassifier, BRepClass_FaceExplorer, BRepClass_FacePassiveClassifier, BRepClass_Intersector, BRepTopAdaptor_FClass2d, CSLib_Class2d, Geom2dHatch_Classifier, Geom2dHatch_Elements, Geom2dHatch_FClass2dOfClassifier, Geom2dHatch_Intersector, TopClass_FaceClassifier, BRepTopAdaptor_TopolTool.

3. Changes in BOPAlgo_PaveFiller::PerformEE() and BOPAlgo_PaveFiller::PerformEF() methods (see BOPAlgo_PaveFiller_3.cxx and BOPAlgo_PaveFiller_5.cxx files): The algorithm of the vertex tolerance computation has been corrected in order to make new vertex cover regions with irregularities (such as Self-intersection).

4. Now, every segment returned by BRepClass_FaceExplorer and/or Geom2dHatch_Elements has some weight, which shows to what extent we can trust this segment in classification process. As result, the classificator returns data obtained from the most reliable segment. These weight are stored in BRepClass_FaceExplorer::RayInfo::myWeight and Geom2dHatch_Elements::RayInfo::myWeight variables.

5. New classes TopClass_RayInfo (describes classification ray joined the classification point with some point in the edge of classified face), TopClass_GeomEdge and TopClass_GeomVertex (store geometrical structure of the edges including pseudo-edges and their vertices) have been created.

6. Method BRepTopAdaptor_FClass2d::PerformInfinitePoint() has been corrected in order to use another (than on the MASTER) point for classification.

7. Method IntTools_EdgeEdge::ComputeLineLine(...) returns intersection point even if the edges have shared vertex. Earlier, it did not it.

8. Creation of pseudo-edges in order to cover gaps in geometrically not-closed (in 2D-space) faces. These face are considered as valid if this gap is covered by some vertex. However, classifier cannot work with "covering vertices". Therefore, new feature (pseudo-edge) has been created. In fact, pseudo-edge is line segment in 2D-space joined two not-closed points.

9. BRepClass_Edge class has been deleted.

10. Check if the section curve cannot be converted to TopoDS_Edge has been added in BOPAlgo_PaveFiller::MakeBlocks() method.

11. Algorithms using face-classifier have been adjusted in order to force them send 3D-tolerance instead of 2D one. I.e. if 3D-representation of classified 2D-point lies ON the edge of the face (the distance from it to the edge is less than the edge tolerance) then it is possible to obtain IN/OUT (not ON) status as result of classification in case when the face tolerance is significantly lesser than the edge tolerance.

12. Since now, following classes apply 3D-tolerance intead of 2D (were applied earlier): Adaptor3d_TopolTool::Classify(...), Adaptor3d_TopolTool::IsThePointOn(...), BRepClass_FClass2dOfFClassifier::Reset(...), BRepClass_FClassifier::BRepClass_FClassifier(...), BRepClass_FClassifier::Perform(...), BRepClass_FaceClassifier::BRepClass_FaceClassifier(...), BRepClass_FaceClassifier::Perform(...), BRepClass_FacePassiveClassifier::Reset(...), BRepClass_Intersector::Perform(...), BRepTopAdaptor_FClass2d::BRepTopAdaptor_FClass2d(...), BRepTopAdaptor_FClass2d::TestOnRestriction(...), BRepTopAdaptor_TopolTool::Classify(...), BRepTopAdaptor_TopolTool::IsThePointOn(...).

13. Modify BRepCheck to report Unorientable shape if a face is classified as UNKNOWN.

14. Do not use vertices tolerances at the edge domain ends in 2d intersection.

15. Check whether the polygonal classifier (CSLib_Class2d) will be able to return correct result has been amended. Namely, CSLib_Class2d is forbidden for using in case of not-closed polygon, self-intersected polygon etc.

16. New method GeomLib::LocalGeometry() has been added. This method returns tangent, normal and curvature in the point of 2D-curve.

17. New DRAW-command "ishole" has been created in BOPTest_LowCommands.cxx file. This command checks if the material of the face is inside (not hole) or outside (hole) of wire enclosed region.

18. New DRAW-command "polyclassify" has been created in BOPTest_LowCommands.cxx file. This command checks if the source point is IN/OUT/ON of the given polygon. See DRAW-help for detail information.

19. Interfaces of DRAW-commands "b2dclassify", "b2dclassifx" have been changed. See helps to the new commands.

20. New DRAW-commands returning the resolutions of curve/surface have been created (see "curvresolution" and "surfresolution"). Non-regression test cases have been created for these commands in geometry/props grid.

21. New DRAW-command "2dpolyline" has been created. It allows creating polygon in 2D-space. Please see help for detailed information.

22. Creation of test cases for issues #28211, #28800 and #29203.

23. New testgrid "lowalgos" has been created. This testgrid is planed to collect all test cases with low-level algorithms (exthrema, intersector, classifier etc.)

24. Code refactoring and documenting.

-----------------------------------------------------------------

Correction of test cases according to their new behavior.

1. tests/blend/tolblend_simple/C1

The reason while this test has become failure is described in the test case tests/lowalgos/classifier/bug28211_19. Earlier, the classifier returned IN-status. Now, it returns ON. And ON-status is correct result.

2. tests/bugs/heal/bug22919

The face contains only two edges, i.e. not-closed (see example in bug22919_FaceKO2.PNG and bug22919_FaceKO4.PNG attached pictures). This gap is covered by pseudo-edges.

3. tests/bugs/modalg_6/bug25908

The reason of changes is explained in tests/lowalgos/classifier/bug28211_20. Earlier, the classifier returned OUT-status. Now, it returns ON. And ON-status is correct result.

4. tests/bugs/modalg_6/bug26953_3

Calls classifier for geometrically not-closed face. Before the fix, classification point was IN the face. Now, it is out (by the reason of entering of pseudo-edges).

5. tests/bugs/modalg_6/bug27341*

They are not regressions/improvements. Simply another behavior. Bug #27341 is not reproduced.

6. tests/de/iges_1/M1
   tests/de/iges_3/A5

Test contains the shape with real coincident edges (see "shape (de iges_1 M1).7z" and "shape (de iges_2 E7).7z" attached archive). Such shape is bad for classification.

7. tests/de/iges_1/O4

The reason of the correction is explained in the issue #29203.

8. tests/de/iges_1/R8

The reason of the script correction is explained in the issue #0029121.

9. tests/de/iges_2/J1
   tests/de/iges_3/B2

Source data are not valid for classification algorithm (self-intersected face like attachments faceDeI2J1.brep and FaceDeI3B2.brep).

10. tests/de/step_1/I1

Contains the face having non-manifold structure (see attached picture "de step_1 I1.PNG").

11. tests/de/step_1/J6
    tests/de/step_2/F4
    tests/de/step_2/O9

Self-intersected shape (see step_2 F4.PNG, de step_2 O9.PNG attached pictures).

12. tests/de/step_1/ZJ7

The face is really invalid (see "de step_1 ZJ7.PNG" attached picture).

13. tests/de/step_2/S1
    tests/de/step_3/D9

Since now, some faces are read with another (in compare with the MASTER) orientation (i.e. as a hole). Therefore, we obtain other isolines.

14. tests/de/step_3/A3
    tests/de/step_3/C3

Invalid (in terms of BRepCheck algorithm) face (let call it "ff") contains edge ff_4 with bending p-curve. Such faces are too hard for classification.

15. tests/bugs/moddata_2/bug299

New result is IMPROVEMENT.

16. tests/bugs/step/bug28256

The shape is really bad for classification (e.g. see message ~70970).

17. tests/heal/fix_shape/A1
    tests/heal/fix_shape/F7

Before the fix, checkshape reported "Bad orientation" about the result shape. However, indeed, the shape is oriented correctly. So the new behavior of the tests can be considered as IMPROVEMENT. On the other hand, the result shape must not be considered as valid (see issue #0023127).

18. tests/prj/base/*

New results are IMPROVEMENT.

19. tests/lowalgos/classifier/bug377

New result is IMPROVEMENT. Additionally, QA-command "OCC377" has been deleted and the test has been rewritten.

20. tests/bugs/iges/bug131_4
    tests/bugs/iges/bug131_8

Difference in the picture is expected. The source face contains really not-oriented wire (see attached pictures "bugs iges bug131_4.PNG" and "bugs iges bug131_8.PNG"). So, the source data is wrong for use in classification algorithm.

21. tests/boolean/bcut_complex/F2

Difference in the picture is expected. The reason is explained in the issue #28211 (see ~71581).

22. tests/offset/with_intersect_80/L6

The test case is BAD as before. The picture is changed only and on the FIX this picture is a bit better than on the MASTER.

23. tests/bugs/moddata_2/bug22746_3

Difference in the picture is expected. New behavior is explained in the issue #28674.

24. tests/de/step_2/M4

Difference in the picture is expected. It is not regression/improvement. Simply, another set of iso-lines.

25. tests/mesh/standard_incmesh/*
    tests/mesh/standard_incmesh_parallel/*
    tests/mesh/standard_mesh/*
    tests/mesh/standard_shading/*
    tests/bugs/vis/*
    tests/bugs/xde/bug23969
    tests/bugs/modalg_2/bug22727
    tests/bugs/modalg_2/bug21261_25
    tests/bugs/modalg_2/bug22790

Difference in the picture is expected. However, general behavior of test cases has not been changed. Therefore, it is not regressions/improvements. Changes is connected with corrections in CSLib_Class2d class (which is used by BRepMesh_Classifier directly - see method BRepMesh_Classifier::Perform()). Consequently, another set of triangles is included to the result. New behavior can be applied.

26. tests/bugs/modalg_7/bug26842_1
    tests/bugs/modalg_7/bug26842_2

Test script has been changed. Therefore, new result picture is expected.

27. tests/de/iges_1/L8

The reason of correction is explained in the issue #28211 (see ~0071639)

28. tests/bugs/modalg_6/bug27830

Regression in performance is expected. The source shape is invalid and contains the faces, which are bad for classification (this situation is described in the issue #27830 - see bug description). Moreover, it is not always clear, which status should be returned (see bugs modalg_6 bug27830.bin attached picture). As result, the current version of the classifier returns differ results in compare with the MASTER. Consequently, many lines, which are excluded from the result on the MASTER, are included in it on the FIX. So, the algorithm handles many points to build the result and of course makes it slowly.

29. tests/bugs/iges/bug16569
    tests/de/iges_1/L8
    tests/bugs/moddata_1/bug22757

Regression in performance is expected. It is connected with two factors: 1) Many classification rays are rejected by the reason that they are not valid (i.e.  only one classification ray is used on the master but the fix uses several rays for check the same face); 2) Extrema point-curve is used in the fix for check ON-status. The 1st item takes
    bugs/iges/bug16569: 92%  is taken on the 1st item and 5% on the 2nd item.
    de/iges_1/L8: 62% and 28% correspondingly

CONCLUSION: new classification algorithm works slowly than previous one with invalid cases.

30. tests/offset/wire_unclosed_outside_0_025/A8
    tests/offset/wire_unclosed_outside_0_005/A8
    tests/offset/wire_unclosed_outside_0_005/A9

Regression in performance is expected. It is connected with using UBTreeFiller which is not used on the MASTER. In the current version of classifier, it is entered in order to check whether the polygon (along the face's p-curve) is self-intersected. So, this innovative increases reliable of the classification algorithm. This criterion has greater priority than performance. Therefore, it cannot be considered as regression.

31. tests/boolean/bopcommon_complex*
    tests/boolean bopcut_complex*
    tests/bugs/modalg_6/bug26316

Some test cases from this grid requires more memory allocation. It is connected with use of UBTreeFiller. So, it is expected and is not a regression.

32. tests/bugs/modalg_7/bug29204

The reason of the correction is explained in item 3 of this commit message.
---
 src/AIS/AIS.cxx                                    |    3 +-
 src/Adaptor3d/Adaptor3d_TopolTool.cxx              |  202 +--
 src/Adaptor3d/Adaptor3d_TopolTool.hxx              |   32 +-
 src/BOPAlgo/BOPAlgo_BuilderFace.cxx                |    6 +-
 src/BOPAlgo/BOPAlgo_PaveFiller_3.cxx               |  104 +-
 src/BOPAlgo/BOPAlgo_PaveFiller_5.cxx               |   42 +-
 src/BOPAlgo/BOPAlgo_PaveFiller_6.cxx               |    4 +
 src/BOPTest/BOPTest_LowCommands.cxx                |  210 ++-
 src/BOPTools/BOPTools_AlgoTools.cxx                |    4 +
 src/BOPTools/BOPTools_AlgoTools2D.cxx              |    8 +-
 src/BOPTools/BOPTools_AlgoTools_2.cxx              |    6 +
 src/BRep/BRep_Tool.hxx                             |    2 +
 src/BRep/FILES                                     |    4 +-
 src/BRepAlgo/BRepAlgo_FaceRestrictor.cxx           |   12 +-
 src/BRepAlgo/BRepAlgo_NormalProjection.cxx         |    8 +-
 src/BRepBlend/BRepBlend_CSWalking.hxx              |    4 +-
 src/BRepBlend/BRepBlend_RstRstLineBuilder.cxx      |  227 ++-
 src/BRepBlend/BRepBlend_RstRstLineBuilder.hxx      |   17 +-
 src/BRepBlend/BRepBlend_SurfRstLineBuilder.cxx     |  211 ++-
 src/BRepBlend/BRepBlend_SurfRstLineBuilder.hxx     |    6 +-
 src/BRepBlend/BRepBlend_Walking.hxx                |   21 +-
 src/BRepBndLib/BRepBndLib.cxx                      |    9 +-
 src/BRepCheck/BRepCheck_Face.cxx                   |   12 +-
 src/BRepClass/BRepClass_Edge.cxx                   |   41 -
 src/BRepClass/BRepClass_Edge.hxx                   |   76 -
 src/BRepClass/BRepClass_Edge.lxx                   |   56 -
 src/BRepClass/BRepClass_FClass2dOfFClassifier.hxx  |   48 +-
 .../BRepClass_FClass2dOfFClassifier_0.cxx          |    5 +-
 src/BRepClass/BRepClass_FClassifier.hxx            |  115 +-
 src/BRepClass/BRepClass_FClassifier_0.cxx          |   10 +-
 src/BRepClass/BRepClass_FaceClassifier.cxx         |  462 +++++-
 src/BRepClass/BRepClass_FaceClassifier.hxx         |   63 +-
 src/BRepClass/BRepClass_FaceExplorer.cxx           |  738 +++++++--
 src/BRepClass/BRepClass_FaceExplorer.hxx           |  187 ++-
 src/BRepClass/BRepClass_FacePassiveClassifier.hxx  |  127 --
 .../BRepClass_FacePassiveClassifier_0.cxx          |   32 -
 src/BRepClass/BRepClass_Intersector.cxx            |  204 +--
 src/BRepClass/BRepClass_Intersector.hxx            |   38 +-
 src/BRepClass/FILES                                |   15 +-
 src/BRepClass3d/BRepClass3d_Intersector3d.cxx      |   21 +-
 src/BRepClass3d/BRepClass3d_Intersector3d.hxx      |   14 +-
 src/BRepClass3d/BRepClass3d_SolidExplorer.cxx      |   22 +-
 src/BRepExtrema/BRepExtrema_DistanceSS.cxx         |   38 +-
 src/BRepExtrema/BRepExtrema_ExtCF.cxx              |    4 +-
 src/BRepExtrema/BRepExtrema_ExtFF.cxx              |   20 +-
 src/BRepExtrema/BRepExtrema_ExtPF.cxx              |    5 +-
 src/BRepFeat/BRepFeat_RibSlot.cxx                  |    7 +-
 .../BRepIntCurveSurface_Inter.cxx                  |   10 +-
 .../BRepIntCurveSurface_Inter.hxx                  |    4 +-
 src/BRepLib/BRepLib_FindSurface.cxx                |    2 +-
 src/BRepLib/BRepLib_MakeFace.cxx                   |    2 +-
 src/BRepMesh/BRepMesh_Classifier.cxx               |    2 +-
 src/BRepOffset/BRepOffset_MakeOffset.cxx           |    4 +-
 src/BRepOffset/BRepOffset_Tool.cxx                 |    8 +-
 src/BRepTopAdaptor/BRepTopAdaptor_FClass2d.cxx     | 1688 ++++++++++++--------
 src/BRepTopAdaptor/BRepTopAdaptor_FClass2d.hxx     |  102 +-
 src/BRepTopAdaptor/BRepTopAdaptor_Tool.cxx         |    3 -
 src/BRepTopAdaptor/BRepTopAdaptor_TopolTool.cxx    |   27 +-
 src/BRepTopAdaptor/BRepTopAdaptor_TopolTool.hxx    |   32 +-
 src/Blend/Blend_CSWalking_1.gxx                    |   27 +-
 src/Blend/Blend_CSWalking_2.gxx                    |   18 +-
 src/Blend/Blend_CSWalking_3.gxx                    |    4 +-
 src/Blend/Blend_CSWalking_4.gxx                    |   41 +-
 src/Blend/Blend_Walking_1.gxx                      |  106 +-
 src/Blend/Blend_Walking_2.gxx                      |   17 +-
 src/Blend/Blend_Walking_3.gxx                      |   35 +-
 src/Blend/Blend_Walking_4.gxx                      |  178 +--
 src/CSLib/CSLib_Class2d.cxx                        |  585 ++++---
 src/CSLib/CSLib_Class2d.hxx                        |   99 +-
 src/ChFi3d/ChFi3d_Builder.hxx                      |   61 +-
 src/ChFi3d/ChFi3d_Builder_0.cxx                    |    8 +-
 src/ChFi3d/ChFi3d_Builder_2.cxx                    |   12 +-
 src/ChFi3d/ChFi3d_Builder_SpKP.cxx                 |    4 +-
 src/ChFi3d/ChFi3d_ChBuilder.hxx                    |    2 +-
 src/ChFi3d/ChFi3d_ChBuilder_C3.cxx                 |    2 -
 src/ChFi3d/ChFi3d_FilBuilder_C3.cxx                |    3 +-
 src/Contap/Contap_Contour.cxx                      |   61 +-
 src/Contap/Contap_Contour.hxx                      |    7 +-
 src/DsgPrs/DsgPrs_ShapeDirPresentation.cxx         |    1 -
 src/Geom2dHatch/Geom2dHatch_Classifier.hxx         |  101 +-
 src/Geom2dHatch/Geom2dHatch_Classifier_0.cxx       |    8 +-
 src/Geom2dHatch/Geom2dHatch_Elements.cxx           |  211 ++-
 src/Geom2dHatch/Geom2dHatch_Elements.hxx           |  109 +-
 .../Geom2dHatch_FClass2dOfClassifier.hxx           |   58 +-
 .../Geom2dHatch_FClass2dOfClassifier_0.cxx         |    3 -
 src/Geom2dHatch/Geom2dHatch_Hatcher.cxx            |   27 +-
 src/Geom2dHatch/Geom2dHatch_Hatcher.hxx            |    2 +-
 src/Geom2dHatch/Geom2dHatch_Intersector.cxx        |   77 +-
 src/Geom2dHatch/Geom2dHatch_Intersector.hxx        |   46 +-
 src/GeomInt/GeomInt_IntSS.cxx                      |   14 +-
 src/GeomInt/GeomInt_IntSS_1.cxx                    |   27 +-
 src/GeomInt/GeomInt_LineConstructor.cxx            |   32 +-
 src/GeomLib/GeomLib.cxx                            |   56 +-
 src/GeomLib/GeomLib.hxx                            |   10 +
 src/GeometryTest/GeometryTest_CurveCommands.cxx    |   42 +
 src/GeometryTest/GeometryTest_SurfaceCommands.cxx  |   36 +-
 src/GeomliteTest/GeomliteTest_CurveCommands.cxx    |   42 +-
 src/HLRBRep/HLRBRep_Data.cxx                       |    2 +-
 src/IntCurvesFace/IntCurvesFace_Intersector.cxx    |   15 +-
 src/IntPatch/IntPatch_ImpPrmIntersection.cxx       |   16 +-
 src/IntPatch/IntPatch_Intersection.hxx             |    9 +-
 src/IntStart/IntStart_SearchInside.gxx             |   29 +-
 src/IntTools/FILES                                 |    4 +-
 src/IntTools/IntTools.hxx                          |    2 -
 src/IntTools/IntTools_Context.cxx                  |   44 +-
 src/IntTools/IntTools_Context.hxx                  |    4 +-
 src/IntTools/IntTools_EdgeEdge.cxx                 |   14 -
 src/IntTools/IntTools_EdgeFace.cxx                 |    8 +-
 src/IntTools/IntTools_FClass2d.cxx                 |  919 -----------
 src/IntTools/IntTools_FClass2d.hxx                 |  120 --
 src/IntTools/IntTools_FaceFace.cxx                 |   32 +-
 src/IntTools/IntTools_Tools.cxx                    |   13 +-
 src/LocOpe/LocOpe_FindEdgesInFace.cxx              |   13 +-
 src/LocOpe/LocOpe_SplitShape.cxx                   |    6 +-
 src/LocOpe/LocOpe_WiresOnShape.cxx                 |    2 +-
 src/QABugs/QABugs_11.cxx                           |   91 --
 src/QABugs/QABugs_8.cxx                            |    2 +-
 .../RWStepVisual_RWPresentationLayerAssignment.cxx |    2 +-
 src/SWDRAW/SWDRAW_ShapeAnalysis.cxx                |    5 +-
 src/ShapeAnalysis/ShapeAnalysis.cxx                |    6 +-
 src/ShapeFix/ShapeFix_ComposeShell.cxx             |    4 +-
 src/ShapeFix/ShapeFix_Face.cxx                     |    8 +-
 src/TNaming/TNaming.cxx                            |   10 +-
 src/TopClass/FILES                                 |    6 +-
 src/TopClass/TopClass_Classifier2d.gxx             |   88 +-
 src/TopClass/TopClass_Classifier3d.gxx             |    2 +-
 src/TopClass/TopClass_FaceClassifier.gxx           |  293 ++--
 src/TopClass/TopClass_FaceClassifier.lxx           |   48 -
 src/TopClass/TopClass_GeomEdge.cxx                 |  247 +++
 src/TopClass/TopClass_GeomEdge.hxx                 |  230 +++
 src/TopClass/TopClass_GeomVertex.cxx               |   52 +
 src/TopClass/TopClass_GeomVertex.hxx               |  111 ++
 src/TopClass/TopClass_RayInfo.hxx                  |  164 ++
 src/TopOpeBRep/TopOpeBRep_PointClassifier.cxx      |    9 +-
 src/TopOpeBRep/TopOpeBRep_PointClassifier.hxx      |    2 +-
 .../TopOpeBRep_VPointInterClassifier.cxx           |   22 +-
 src/TopOpeBRepBuild/TopOpeBRepBuild_Builder1.cxx   |    3 +-
 src/TopOpeBRepBuild/TopOpeBRepBuild_GridSS.cxx     |    9 +-
 src/TopOpeBRepBuild/TopOpeBRepBuild_Tools.cxx      |    2 +-
 .../TopOpeBRepBuild_WireEdgeClassifier.cxx         |   40 +-
 .../TopOpeBRepBuild_WireEdgeClassifier.hxx         |    8 +-
 src/TopOpeBRepBuild/TopOpeBRepBuild_ffsfs.cxx      |    3 +-
 src/TopOpeBRepTool/TopOpeBRepTool_CLASSI.cxx       |    6 +-
 .../TopOpeBRepTool_ShapeClassifier.cxx             |  135 +-
 src/TopOpeBRepTool/TopOpeBRepTool_face.cxx         |    3 +-
 tests/blend/complex/A3                             |    3 +
 tests/blend/tolblend_simple/C1                     |    2 +
 tests/boolean/bfuse_complex/M7                     |    4 +
 tests/bugs/heal/bug22919                           |    7 +-
 tests/bugs/modalg_2/bug23341                       |   22 -
 tests/bugs/modalg_5/bug23625_2                     |    2 +-
 tests/bugs/modalg_5/bug23777                       |   22 -
 tests/bugs/modalg_5/bug23849_2                     |   23 -
 tests/bugs/modalg_5/bug24422                       |   27 -
 tests/bugs/modalg_5/bug25969                       |   37 -
 tests/bugs/modalg_5/bug25969_std                   |   37 -
 tests/bugs/modalg_6/bug25908                       |    6 +-
 tests/bugs/modalg_6/bug26206                       |   26 -
 tests/bugs/modalg_6/bug26953_3                     |    2 +-
 tests/bugs/modalg_6/bug27434                       |   21 -
 tests/bugs/modalg_6/bug28211_1                     |   25 +
 tests/bugs/modalg_6/bug28211_8                     |   24 +
 tests/bugs/modalg_6/bug28800                       |   15 +
 tests/bugs/modalg_7/bug23667                       |    2 +
 tests/bugs/modalg_7/bug26842_1                     |    9 +-
 tests/bugs/modalg_7/bug26842_2                     |   20 +-
 tests/bugs/modalg_7/bug28764                       |    3 +-
 tests/bugs/modalg_7/bug29204                       |    2 +-
 tests/bugs/moddata_1/buc60609                      |   21 -
 tests/bugs/moddata_1/bug22494                      |   27 -
 tests/bugs/moddata_2/bug22746_3                    |    2 +
 tests/bugs/moddata_2/bug23244                      |   36 -
 tests/bugs/moddata_2/bug299                        |    4 +-
 tests/bugs/moddata_2/bug377                        |   22 -
 tests/bugs/moddata_2/bug538                        |   25 -
 tests/bugs/step/bug28256                           |    6 +-
 tests/de/iges_2/C5                                 |    1 +
 tests/de/iges_2/G7                                 |    2 +-
 tests/de/iges_2/H4                                 |    1 +
 tests/de/iges_3/A1                                 |    1 +
 tests/de/step_3/E6                                 |    1 +
 tests/heal/fix_shape/A1                            |   11 +-
 tests/heal/fix_shape/F7                            |   11 +-
 tests/heal/surface_to_bspline/F2                   |    2 +-
 tests/lowalgos/classifier/buc60609                 |   21 +
 tests/lowalgos/classifier/bug22494                 |   26 +
 tests/lowalgos/classifier/bug23244                 |   36 +
 tests/lowalgos/classifier/bug23341                 |   21 +
 tests/lowalgos/classifier/bug23777                 |   22 +
 tests/lowalgos/classifier/bug23849_2               |   23 +
 tests/lowalgos/classifier/bug24422                 |   25 +
 tests/lowalgos/classifier/bug25969                 |   37 +
 tests/lowalgos/classifier/bug25969_std             |   37 +
 tests/lowalgos/classifier/bug26206                 |   26 +
 tests/lowalgos/classifier/bug27434                 |   21 +
 tests/lowalgos/classifier/bug28211_10              |   36 +
 tests/lowalgos/classifier/bug28211_11              |   37 +
 tests/lowalgos/classifier/bug28211_12              |   49 +
 tests/lowalgos/classifier/bug28211_13              |   34 +
 tests/lowalgos/classifier/bug28211_14              |   47 +
 tests/lowalgos/classifier/bug28211_15              |   35 +
 tests/lowalgos/classifier/bug28211_16              |   35 +
 tests/lowalgos/classifier/bug28211_17              |   29 +
 tests/lowalgos/classifier/bug28211_18              |   60 +
 tests/lowalgos/classifier/bug28211_19              |   39 +
 tests/lowalgos/classifier/bug28211_2               |   69 +
 tests/lowalgos/classifier/bug28211_20              |   43 +
 tests/lowalgos/classifier/bug28211_21              |   43 +
 tests/lowalgos/classifier/bug28211_22              |   38 +
 tests/lowalgos/classifier/bug28211_23              |   30 +
 tests/lowalgos/classifier/bug28211_24              |   41 +
 tests/lowalgos/classifier/bug28211_25              |   42 +
 tests/lowalgos/classifier/bug28211_26              |   42 +
 tests/lowalgos/classifier/bug28211_27              |   50 +
 tests/lowalgos/classifier/bug28211_28              |   37 +
 tests/lowalgos/classifier/bug28211_29              |  116 ++
 tests/lowalgos/classifier/bug28211_3               |   69 +
 tests/lowalgos/classifier/bug28211_30              |   34 +
 tests/lowalgos/classifier/bug28211_31              |   38 +
 tests/lowalgos/classifier/bug28211_32              |   61 +
 tests/lowalgos/classifier/bug28211_33              |   50 +
 tests/lowalgos/classifier/bug28211_34              |   62 +
 tests/lowalgos/classifier/bug28211_35              |   60 +
 tests/lowalgos/classifier/bug28211_36              |   54 +
 tests/lowalgos/classifier/bug28211_37              |   50 +
 tests/lowalgos/classifier/bug28211_38              |   50 +
 tests/lowalgos/classifier/bug28211_39              |   62 +
 tests/lowalgos/classifier/bug28211_4               |   69 +
 tests/lowalgos/classifier/bug28211_40              |   49 +
 tests/lowalgos/classifier/bug28211_5               |   69 +
 tests/lowalgos/classifier/bug28211_6               |   36 +
 tests/lowalgos/classifier/bug28211_7               |   60 +
 tests/lowalgos/classifier/bug28211_9               |   29 +
 tests/lowalgos/classifier/bug29203_1               |   34 +
 tests/lowalgos/classifier/bug29203_2               |   36 +
 tests/lowalgos/classifier/bug377                   |   99 ++
 tests/lowalgos/classifier/bug538                   |   43 +
 tests/lowalgos/grids.list                          |    3 +-
 tests/lowalgos/parse.rules                         |    2 +
 tests/sewing/tol_100/K1                            |    1 -
 240 files changed, 7905 insertions(+), 5397 deletions(-)
 delete mode 100644 src/BRepClass/BRepClass_Edge.cxx
 delete mode 100644 src/BRepClass/BRepClass_Edge.hxx
 delete mode 100644 src/BRepClass/BRepClass_Edge.lxx
 delete mode 100644 src/BRepClass/BRepClass_FacePassiveClassifier.hxx
 delete mode 100644 src/BRepClass/BRepClass_FacePassiveClassifier_0.cxx
 delete mode 100644 src/IntTools/IntTools_FClass2d.cxx
 delete mode 100644 src/IntTools/IntTools_FClass2d.hxx
 delete mode 100644 src/TopClass/TopClass_FaceClassifier.lxx
 create mode 100644 src/TopClass/TopClass_GeomEdge.cxx
 create mode 100644 src/TopClass/TopClass_GeomEdge.hxx
 create mode 100644 src/TopClass/TopClass_GeomVertex.cxx
 create mode 100644 src/TopClass/TopClass_GeomVertex.hxx
 create mode 100644 src/TopClass/TopClass_RayInfo.hxx
 delete mode 100755 tests/bugs/modalg_2/bug23341
 delete mode 100755 tests/bugs/modalg_5/bug23777
 delete mode 100644 tests/bugs/modalg_5/bug23849_2
 delete mode 100644 tests/bugs/modalg_5/bug24422
 delete mode 100644 tests/bugs/modalg_5/bug25969
 delete mode 100644 tests/bugs/modalg_5/bug25969_std
 delete mode 100644 tests/bugs/modalg_6/bug26206
 delete mode 100644 tests/bugs/modalg_6/bug27434
 create mode 100644 tests/bugs/modalg_6/bug28211_1
 create mode 100644 tests/bugs/modalg_6/bug28211_8
 create mode 100644 tests/bugs/modalg_6/bug28800
 delete mode 100755 tests/bugs/moddata_1/buc60609
 delete mode 100755 tests/bugs/moddata_1/bug22494
 delete mode 100755 tests/bugs/moddata_2/bug23244
 delete mode 100755 tests/bugs/moddata_2/bug377
 delete mode 100755 tests/bugs/moddata_2/bug538
 create mode 100644 tests/lowalgos/classifier/buc60609
 create mode 100644 tests/lowalgos/classifier/bug22494
 create mode 100644 tests/lowalgos/classifier/bug23244
 create mode 100644 tests/lowalgos/classifier/bug23341
 create mode 100644 tests/lowalgos/classifier/bug23777
 create mode 100644 tests/lowalgos/classifier/bug23849_2
 create mode 100644 tests/lowalgos/classifier/bug24422
 create mode 100644 tests/lowalgos/classifier/bug25969
 create mode 100644 tests/lowalgos/classifier/bug25969_std
 create mode 100644 tests/lowalgos/classifier/bug26206
 create mode 100644 tests/lowalgos/classifier/bug27434
 create mode 100644 tests/lowalgos/classifier/bug28211_10
 create mode 100644 tests/lowalgos/classifier/bug28211_11
 create mode 100644 tests/lowalgos/classifier/bug28211_12
 create mode 100644 tests/lowalgos/classifier/bug28211_13
 create mode 100644 tests/lowalgos/classifier/bug28211_14
 create mode 100644 tests/lowalgos/classifier/bug28211_15
 create mode 100644 tests/lowalgos/classifier/bug28211_16
 create mode 100644 tests/lowalgos/classifier/bug28211_17
 create mode 100644 tests/lowalgos/classifier/bug28211_18
 create mode 100644 tests/lowalgos/classifier/bug28211_19
 create mode 100644 tests/lowalgos/classifier/bug28211_2
 create mode 100644 tests/lowalgos/classifier/bug28211_20
 create mode 100644 tests/lowalgos/classifier/bug28211_21
 create mode 100644 tests/lowalgos/classifier/bug28211_22
 create mode 100644 tests/lowalgos/classifier/bug28211_23
 create mode 100644 tests/lowalgos/classifier/bug28211_24
 create mode 100644 tests/lowalgos/classifier/bug28211_25
 create mode 100644 tests/lowalgos/classifier/bug28211_26
 create mode 100644 tests/lowalgos/classifier/bug28211_27
 create mode 100644 tests/lowalgos/classifier/bug28211_28
 create mode 100644 tests/lowalgos/classifier/bug28211_29
 create mode 100644 tests/lowalgos/classifier/bug28211_3
 create mode 100644 tests/lowalgos/classifier/bug28211_30
 create mode 100644 tests/lowalgos/classifier/bug28211_31
 create mode 100644 tests/lowalgos/classifier/bug28211_32
 create mode 100644 tests/lowalgos/classifier/bug28211_33
 create mode 100644 tests/lowalgos/classifier/bug28211_34
 create mode 100644 tests/lowalgos/classifier/bug28211_35
 create mode 100644 tests/lowalgos/classifier/bug28211_36
 create mode 100644 tests/lowalgos/classifier/bug28211_37
 create mode 100644 tests/lowalgos/classifier/bug28211_38
 create mode 100644 tests/lowalgos/classifier/bug28211_39
 create mode 100644 tests/lowalgos/classifier/bug28211_4
 create mode 100644 tests/lowalgos/classifier/bug28211_40
 create mode 100644 tests/lowalgos/classifier/bug28211_5
 create mode 100644 tests/lowalgos/classifier/bug28211_6
 create mode 100644 tests/lowalgos/classifier/bug28211_7
 create mode 100644 tests/lowalgos/classifier/bug28211_9
 create mode 100644 tests/lowalgos/classifier/bug29203_1
 create mode 100644 tests/lowalgos/classifier/bug29203_2
 create mode 100644 tests/lowalgos/classifier/bug377
 create mode 100644 tests/lowalgos/classifier/bug538

diff --git a/src/AIS/AIS.cxx b/src/AIS/AIS.cxx
index 60b6067..95203a1 100644
--- a/src/AIS/AIS.cxx
+++ b/src/AIS/AIS.cxx
@@ -1221,8 +1221,7 @@ void AIS::InitLengthBetweenCurvilinearFaces (const TopoDS_Face&    theFirstFace,
     // Now there is projection of FirstAttach onto SecondSurf in aProjector
     BRepTopAdaptor_FClass2d aClassifier (theSecondFace, Precision::Confusion());
 
-    TopAbs_State aState = 
-      aClassifier.Perform (gp_Pnt2d (aPU, aPV), theSecondSurf->IsUPeriodic() || theSecondSurf->IsVPeriodic());
+    TopAbs_State aState = aClassifier.Perform (gp_Pnt2d (aPU, aPV), Standard_True);
 
     if (aState == TopAbs_OUT || aState == TopAbs_UNKNOWN)
     {
diff --git a/src/Adaptor3d/Adaptor3d_TopolTool.cxx b/src/Adaptor3d/Adaptor3d_TopolTool.cxx
index c22fc52..3795a7e 100644
--- a/src/Adaptor3d/Adaptor3d_TopolTool.cxx
+++ b/src/Adaptor3d/Adaptor3d_TopolTool.cxx
@@ -275,23 +275,39 @@ void Adaptor3d_TopolTool::NextVertex ()
   idVtx++;
 }
 
-
-TopAbs_State Adaptor3d_TopolTool::Classify(const gp_Pnt2d& P,
-					 const Standard_Real Tol,
-					 const Standard_Boolean )
-//					 const Standard_Boolean RecadreOnPeriodic)
+//=======================================================================
+//function : Classify
+//purpose  : 
+//=======================================================================
+TopAbs_State Adaptor3d_TopolTool::Classify(const gp_Pnt2d& theP,
+                                           const Standard_Real theTol3D,
+                                           const Standard_Boolean /*theIsAdjustReq*/)
 {
+  const Standard_Real aTolU = myS->UResolution(theTol3D),
+                      aTolV = myS->VResolution(theTol3D);
+  return Classify(theP, aTolU, aTolV);
+}
 
-  Standard_Real U = P.X();
-  Standard_Real V = P.Y();
+
+//=======================================================================
+//function : Classify
+//purpose  : 
+//=======================================================================
+TopAbs_State Adaptor3d_TopolTool::Classify(const gp_Pnt2d& theP,
+                                           const Standard_Real theTolU,
+                                           const Standard_Real theTolV)
+{
+  const Standard_Real aU = theP.X(), aV = theP.Y();
 
   if (nbRestr == 4) {
-    if ((U < Uinf - Tol) || (U > Usup + Tol) ||
-      (V < Vinf - Tol) || (V > Vsup + Tol)) {
+    if (((Uinf-aU) > theTolU) || ((aU-Usup) > theTolU) ||
+        ((Vinf-aV) > theTolV) || ((aV-Vsup) > theTolV))
+    {
         return TopAbs_OUT;
     }
-    if ((Abs(U - Uinf) <= Tol) || (Abs(U - Usup) <= Tol) ||
-      (Abs(V - Vinf) <= Tol) || (Abs(V - Vsup) <= Tol)) {
+    
+    if((Abs(aU - Uinf) <= theTolU) || (Abs(aU - Usup) <= theTolU) ||
+       (Abs(aV - Vinf) <= theTolV) || (Abs(aV - Vsup) <= theTolV)) {
         return TopAbs_ON;
     }
     return TopAbs_IN;
@@ -308,43 +324,43 @@ TopAbs_State Adaptor3d_TopolTool::Classify(const gp_Pnt2d& P,
     }
     else if (Precision::IsNegativeInfinite(Uinf)) {
       surumin = Standard_False;
-      if (U >= Usup+Tol) {
+      if ((aU-Usup) >= theTolU) {
 	      dansu = Standard_False;
 	      surumax = Standard_False;
       }
       else {
 	      dansu = Standard_True;
 	      surumax = Standard_False;
-	      if (Abs(U-Usup)<=Tol) {
+              if (Abs(aU - Usup) <= theTolU) {
 	        surumax = Standard_True;
 	      }
       }
     }
     else if (Precision::IsPositiveInfinite(Usup)) {
       surumax = Standard_False;
-      if (U < Uinf-Tol) {
+      if (theTolU < Uinf - aU) {
         dansu = Standard_False;
         surumin = Standard_False;
       }
       else {
         dansu = Standard_True;
         surumin = Standard_False;
-        if (Abs(U-Uinf)<=Tol) {
+        if (Abs(aU - Uinf) <= theTolU) {
           surumin = Standard_True;
         }
       }
     }
     else {
-      if ((U < Uinf - Tol) || (U > Usup + Tol)) {
+      if (((Uinf - aU) > theTolU) || ((aU - Usup) > theTolU)) {
         surumin = surumax = dansu = Standard_False;
       }
       else {
         dansu = Standard_True;
         surumin = surumax = Standard_False;
-        if (Abs(U-Uinf)<=Tol) {
+        if (Abs(aU - Uinf) <= theTolU) {
           surumin = Standard_True;
         }
-        else if (Abs(U-Usup)<=Tol) {
+        else if (Abs(aU - Usup) <= theTolU) {
           surumax = Standard_True;
         }
       }
@@ -357,43 +373,43 @@ TopAbs_State Adaptor3d_TopolTool::Classify(const gp_Pnt2d& P,
     }
     else if (Precision::IsNegativeInfinite(Vinf)) {
       survmin = Standard_False;
-      if (V > Vsup+Tol) {
+      if ((aV - Vsup) > theTolV) {
         dansv = Standard_False;
         survmax = Standard_False;
       }
       else {
         dansv = Standard_True;
         survmax = Standard_False;
-        if (Abs(V-Vsup)<=Tol) {
+        if (Abs(aV - Vsup) <= theTolV) {
           survmax = Standard_True;
         }
       }
     }
     else if (Precision::IsPositiveInfinite(Vsup)) {
       survmax = Standard_False;
-      if (V < Vinf-Tol) {
+      if (theTolV < (Vinf - aV)) {
         dansv = Standard_False;
         survmin = Standard_False;
       }
       else {
         dansv = Standard_True;
         survmin = Standard_False;
-        if (Abs(V-Vinf)<=Tol) {
+        if (Abs(aV - Vinf) <= theTolV) {
           survmin = Standard_True;
         }
       }
     }
     else {
-      if ((V < Vinf - Tol) || (V > Vsup + Tol)) {
+      if ((theTolV < (Vinf - aV)) || ((aV - Vsup) > theTolV)) {
         survmin = survmax = dansv = Standard_False;
       }
       else {
         dansv = Standard_True;
         survmin = survmax = Standard_False;
-        if (Abs(V-Vinf)<=Tol) {
+        if (Abs(aV - Vinf) <= theTolV) {
           survmin = Standard_True;
         }
-        else if (Abs(V-Vsup)<=Tol) {
+        else if (Abs(aV - Vsup) <= theTolV) {
           survmax = Standard_True;
         }
       }
@@ -409,139 +425,11 @@ TopAbs_State Adaptor3d_TopolTool::Classify(const gp_Pnt2d& P,
   }
 }
 
-
-
-Standard_Boolean  Adaptor3d_TopolTool::IsThePointOn(const gp_Pnt2d& P,
-					     const Standard_Real Tol,
-					     const Standard_Boolean )
-//					     const Standard_Boolean RecadreOnPeriodic)
+Standard_Boolean Adaptor3d_TopolTool::IsThePointOn(const gp_Pnt2d& theP,
+                                                   const Standard_Real theTol3D,
+                                                   const Standard_Boolean theIsAdjustReq)
 {
-
-  Standard_Real U = P.X();
-  Standard_Real V = P.Y();
-
-  if (nbRestr == 4) {
-    if ((U < Uinf - Tol) || (U > Usup + Tol) ||
-	(V < Vinf - Tol) || (V > Vsup + Tol)) {
-      return(Standard_False);
-    }
-    if ((Abs(U - Uinf) <= Tol) || (Abs(U - Usup) <= Tol) ||
-	(Abs(V - Vinf) <= Tol) || (Abs(V - Vsup) <= Tol)) {
-      return(Standard_True);
-    }
-    return(Standard_False);
-  }
-  else if (nbRestr == 0) {
-    return(Standard_False);
-  }
-  else {
-    Standard_Boolean dansu,dansv,surumin,surumax,survmin,survmax;
-    if (Precision::IsNegativeInfinite(Uinf) && 
-	Precision::IsPositiveInfinite(Usup)) {
-      dansu = Standard_True;
-      surumin = surumax = Standard_False;
-    }
-    else if (Precision::IsNegativeInfinite(Uinf)) {
-      surumin = Standard_False;
-      if (U >= Usup+Tol) {
-	dansu = Standard_False;
-	surumax = Standard_False;
-      }
-      else {
-	dansu = Standard_True;
-	surumax = Standard_False;
-	if (Abs(U-Usup)<=Tol) {
-	  surumax = Standard_True;
-	}
-      }
-    }
-    else if (Precision::IsPositiveInfinite(Usup)) {
-      surumax = Standard_False;
-      if (U < Uinf-Tol) {
-	dansu = Standard_False;
-	surumin = Standard_False;
-      }
-      else {
-	dansu = Standard_True;
-	surumin = Standard_False;
-	if (Abs(U-Uinf)<=Tol) {
-	  surumin = Standard_True;
-	}
-      }
-    }
-    else {
-      if ((U < Uinf - Tol) || (U > Usup + Tol)) {
-	surumin = surumax = dansu = Standard_False;
-      }
-      else {
-	dansu = Standard_True;
-	surumin = surumax = Standard_False;
-	if (Abs(U-Uinf)<=Tol) {
-	  surumin = Standard_True;
-	}
-	else if (Abs(U-Usup)<=Tol) {
-	  surumax = Standard_True;
-	}
-      }
-    }
-
-    if (Precision::IsNegativeInfinite(Vinf) &&
-	Precision::IsPositiveInfinite(Vsup)) {
-      dansv = Standard_True;
-      survmin = survmax = Standard_False;
-    }
-    else if (Precision::IsNegativeInfinite(Vinf)) {
-      survmin = Standard_False;
-      if (V > Vsup+Tol) {
-	dansv = Standard_False;
-	survmax = Standard_False;
-      }
-      else {
-	dansv = Standard_True;
-	survmax = Standard_False;
-	if (Abs(V-Vsup)<=Tol) {
-	  survmax = Standard_True;
-	}
-      }
-    }
-    else if (Precision::IsPositiveInfinite(Vsup)) {
-      survmax = Standard_False;
-      if (V < Vinf-Tol) {
-	dansv = Standard_False;
-	survmin = Standard_False;
-      }
-      else {
-	dansv = Standard_True;
-	survmin = Standard_False;
-	if (Abs(V-Vinf)<=Tol) {
-	  survmin = Standard_True;
-	}
-      }
-    }
-    else {
-      if ((V < Vinf - Tol) || (V > Vsup + Tol)) {
-	survmin = survmax = dansv = Standard_False;
-      }
-      else {
-	dansv = Standard_True;
-	survmin = survmax = Standard_False;
-	if (Abs(V-Vinf)<=Tol) {
-	  survmin = Standard_True;
-	}
-	else if (Abs(V-Vsup)<=Tol) {
-	  survmax = Standard_True;
-	}
-      }
-    }
-
-    if (!dansu || !dansv) {
-      return(Standard_False);
-    }
-    if (surumin || survmin || surumax || survmax) {
-      return(Standard_True);
-    }
-    return(Standard_False);;
-  }
+  return (Classify(theP, theTol3D, theIsAdjustReq) == TopAbs_ON);
 }
 
 
diff --git a/src/Adaptor3d/Adaptor3d_TopolTool.hxx b/src/Adaptor3d/Adaptor3d_TopolTool.hxx
index d2bfa34..6eb8525 100644
--- a/src/Adaptor3d/Adaptor3d_TopolTool.hxx
+++ b/src/Adaptor3d/Adaptor3d_TopolTool.hxx
@@ -40,7 +40,7 @@ DEFINE_STANDARD_HANDLE(Adaptor3d_TopolTool, Standard_Transient)
 //! from Adaptor3d.
 //! All methods and fields may be redefined when
 //! inheriting from this class.
-//! This class is used to instantiate algorithmes
+//! This class is used to instantiate algorithms
 //! as Intersection, outlines,...
 class Adaptor3d_TopolTool : public Standard_Transient
 {
@@ -74,9 +74,27 @@ public:
   
   Standard_EXPORT virtual void NextVertex();
   
-  Standard_EXPORT virtual TopAbs_State Classify (const gp_Pnt2d& P, const Standard_Real Tol, const Standard_Boolean ReacdreOnPeriodic = Standard_True);
-  
-  Standard_EXPORT virtual Standard_Boolean IsThePointOn (const gp_Pnt2d& P, const Standard_Real Tol, const Standard_Boolean ReacdreOnPeriodic = Standard_True);
+  //! Classifies theP relatively to the domain of myS.
+  //! theTol3D is the 3D-tolerance. Respective 2D-tolerance
+  //! is recomputed inside this method.
+  //! The parameter ReacdreOnPeriodic is not used in
+  //! this method (is kept for compatibility with
+  //! inherited classes).
+  Standard_EXPORT virtual 
+        TopAbs_State Classify(const gp_Pnt2d& theP,
+                              const Standard_Real theTol3D,
+                              const Standard_Boolean ReacdreOnPeriodic = Standard_True);
+
+  //! Returns TRUE if theP is on the boundary of the domain of myS.
+  //! theTol3D is the 3D-tolerance. Respective 2D-tolerance
+  //! is recomputed inside this method.
+  //! The parameter ReacdreOnPeriodic is not used in
+  //! this method (is kept for compatibility with
+  //! inherited classes).
+  Standard_EXPORT virtual
+        Standard_Boolean IsThePointOn(const gp_Pnt2d& theP,
+                                      const Standard_Real theTol3D,
+                                      const Standard_Boolean ReacdreOnPeriodic = Standard_True);
   
   //! If the function returns the orientation of the arc.
   //! If the orientation is FORWARD or REVERSED, the arc is
@@ -158,6 +176,12 @@ public:
 
 protected:
 
+  //! Classifies theP relatively to the domain of myS.
+  //! theTolU and theTolV are the 2D-tolerances.
+  Standard_EXPORT
+        TopAbs_State Classify(const gp_Pnt2d& theP,
+                              const Standard_Real theTolU,
+                              const Standard_Real theTolV);
 
   Handle(Adaptor3d_HSurface) myS;
   Standard_Integer myNbSamplesU;
diff --git a/src/BOPAlgo/BOPAlgo_BuilderFace.cxx b/src/BOPAlgo/BOPAlgo_BuilderFace.cxx
index 2caa3ff..1066774 100644
--- a/src/BOPAlgo/BOPAlgo_BuilderFace.cxx
+++ b/src/BOPAlgo/BOPAlgo_BuilderFace.cxx
@@ -36,7 +36,7 @@
 #include <gp_Pnt2d.hxx>
 #include <gp_Vec.hxx>
 #include <IntTools_Context.hxx>
-#include <IntTools_FClass2d.hxx>
+#include <BRepTopAdaptor_FClass2d.hxx>
 #include <NCollection_DataMap.hxx>
 #include <NCollection_UBTreeFiller.hxx>
 #include <TColStd_MapIntegerHasher.hxx>
@@ -423,7 +423,7 @@ void BOPAlgo_BuilderFace::PerformAreas()
     if (!bIsGrowth)
     {
       // Fast check did not give the result, run classification
-      IntTools_FClass2d& aClsf = myContext->FClass2d(aFace);
+      BRepTopAdaptor_FClass2d& aClsf = myContext->FClass2d(aFace);
       bIsGrowth = !aClsf.IsHole();
     }
 
@@ -721,7 +721,7 @@ Standard_Boolean IsInside(const TopoDS_Shape& theWire,
 
   // Get classification tool from the context
   const TopoDS_Face& aF = TopoDS::Face(theF);
-  IntTools_FClass2d& aClassifier = theContext->FClass2d(aF);
+  BRepTopAdaptor_FClass2d& aClassifier = theContext->FClass2d(aF);
 
   Standard_Boolean isInside = Standard_False;
 
diff --git a/src/BOPAlgo/BOPAlgo_PaveFiller_3.cxx b/src/BOPAlgo/BOPAlgo_PaveFiller_3.cxx
index cd04b75..82ca9b2 100644
--- a/src/BOPAlgo/BOPAlgo_PaveFiller_3.cxx
+++ b/src/BOPAlgo/BOPAlgo_PaveFiller_3.cxx
@@ -313,7 +313,7 @@ void BOPAlgo_PaveFiller::PerformEE()
           }
           //
           Standard_Boolean bIsOnPave[4], bFlag;
-          Standard_Integer nV[4], j;
+          Standard_Integer nV[4];
           Standard_Real aT1, aT2, aTol;
           TopoDS_Vertex aVnew;
           IntTools_Range aCR1, aCR2;
@@ -326,7 +326,7 @@ void BOPAlgo_PaveFiller::PerformEE()
           //decide to keep the pave or not
           bIsOnPave[0] = IntTools_Tools::IsOnPave1(aT1, aR11, aTol) ||
             IntTools_Tools::IsOnPave1(aR11.First(), aCR1, aTol);
-          bIsOnPave[1] = IntTools_Tools::IsOnPave1(aT1, aR12, aTol) || 
+          bIsOnPave[1] = IntTools_Tools::IsOnPave1(aT1, aR12, aTol) ||
             IntTools_Tools::IsOnPave1(aR12.Last(), aCR1, aTol);
           bIsOnPave[2] = IntTools_Tools::IsOnPave1(aT2, aR21, aTol) ||
             IntTools_Tools::IsOnPave1(aR21.First(), aCR2, aTol);
@@ -336,19 +336,48 @@ void BOPAlgo_PaveFiller::PerformEE()
           aPB1->Indices(nV[0], nV[1]);
           aPB2->Indices(nV[2], nV[3]);
           //
-          if((bIsOnPave[0] && bIsOnPave[2]) || 
-             (bIsOnPave[0] && bIsOnPave[3]) ||
-             (bIsOnPave[1] && bIsOnPave[2]) || 
-             (bIsOnPave[1] && bIsOnPave[3])) {
-            continue;
+          BOPTools_AlgoTools::MakeNewVertex(aE1, aT1, aE2, aT2, aVnew);
+          const gp_Pnt aPnew = BRep_Tool::Pnt(aVnew);
+
+          {
+            Standard_Boolean isOnTwoPaves = Standard_False;
+            for (Standard_Integer aPaveI = 0; (!isOnTwoPaves) && (aPaveI < 2); aPaveI++)
+            {
+              for (Standard_Integer aPaveJ = 2; aPaveJ < 4; aPaveJ++)
+              {
+                if (bIsOnPave[aPaveI] && bIsOnPave[aPaveJ])
+                {
+                  if (nV[aPaveI] == nV[aPaveJ])
+                  {
+                    const TopoDS_Vertex& aV = TopoDS::Vertex(myDS->Shape(nV[aPaveI]));
+                    const gp_Pnt aP2(BRep_Tool::Pnt(aV));
+                    UpdateVertex(nV[aPaveI], aPnew.Distance(aP2));
+                  }
+
+                  isOnTwoPaves = Standard_True;
+                  break;
+                }
+              }
+            }
+
+            if (isOnTwoPaves)
+              continue;
           }
           //
           bFlag = Standard_False;
-          for (j = 0; j < 4; ++j) {
+          for (Standard_Integer j = 0; j < 4; ++j) {
             if (bIsOnPave[j]) {
               //add interf VE(nV[j], nE)
               Handle(BOPDS_PaveBlock)& aPB = (j < 2) ? aPB2 : aPB1;
               bFlag = ForceInterfVE(nV[j], aPB, aMEdges);
+
+              if(bFlag)
+              {
+                const TopoDS_Vertex& aV = TopoDS::Vertex(myDS->Shape(nV[j]));
+                const gp_Pnt aP2 = BRep_Tool::Pnt(aV);
+                UpdateVertex(nV[j], aPnew.Distance(aP2));
+              }
+
               break;
             }
           }
@@ -359,14 +388,15 @@ void BOPAlgo_PaveFiller::PerformEE()
             continue;
           }
           //
-          BOPTools_AlgoTools::MakeNewVertex(aE1, aT1, aE2, aT2, aVnew);
           Standard_Real aTolVnew = BRep_Tool::Tolerance(aVnew);
           if (bAnalytical) {
             // increase tolerance for Line/Line intersection, but do not update 
             // the vertex till its intersection with some other shape
             Standard_Real aTolMin = (BRepAdaptor_Curve(aE1).GetType() == GeomAbs_Line) ?
-              (aCR1.Last() - aCR1.First()) / 2. : (aCR2.Last() - aCR2.First()) / 2.;
-            if (aTolMin > aTolVnew) {
+                                Max(Abs(aCR1.Last() - aT1), Abs(aCR1.First() - aT1)) :
+                                Max(Abs(aCR2.Last() - aT2), Abs(aCR2.First() - aT2));
+            if (aTolMin > aTolVnew)
+            {
               aTolVnew = aTolMin;
             }
           }
@@ -375,10 +405,10 @@ void BOPAlgo_PaveFiller::PerformEE()
             Standard_Integer nVS[2], iFound;
             Standard_Real aTolVx, aD2, aDT2;
             TColStd_MapOfInteger aMV;
-            gp_Pnt aPnew, aPx;
+            gp_Pnt aPx;
             //
             iFound=0;
-            j=-1;
+            Standard_Integer j=-1;
             aMV.Add(nV[0]);
             aMV.Add(nV[1]);
             //
@@ -391,8 +421,6 @@ void BOPAlgo_PaveFiller::PerformEE()
               nVS[j]=nV[3];
             }
             //
-            aPnew=BRep_Tool::Pnt(aVnew);
-            //
             for (Standard_Integer k1=0; k1<=j; ++k1) {
               const TopoDS_Vertex& aVx= *(TopoDS_Vertex*)&(myDS->Shape(nVS[k1]));
               aTolVx=BRep_Tool::Tolerance(aVx);
@@ -461,20 +489,20 @@ void BOPAlgo_PaveFiller::PerformEE()
   //=========================================
   BOPAlgo_Tools::PerformCommonBlocks(aMPBLPB, aAllocator, myDS);
   PerformNewVertices(aMVCPB, aAllocator);
-  //
+    //
   if (aMEdges.Extent()) {
     Standard_Integer aNbV = aMVCPB.Extent();
-    for (i = 1; i <= aNbV; ++i) {
+    for (i=1; i<=aNbV; ++i) {
       Handle(BOPDS_PaveBlock) aPB1, aPB2;
-      const BOPDS_CoupleOfPaveBlocks& aCPB = aMVCPB.FindFromIndex(i);
-      aCPB.PaveBlocks(aPB1, aPB2);
+      const BOPDS_CoupleOfPaveBlocks& aCPB=aMVCPB.FindFromIndex(i);
+      aCPB.PaveBlocks(aPB1, aPB2); 
       //
       aMEdges.Remove(aPB1->OriginalEdge());
       aMEdges.Remove(aPB2->OriginalEdge());
     }
-    //
+  //
     SplitPaveBlocks(aMEdges, Standard_False);
-  }
+    }
   //
   //-----------------------------------------------------scope t
   aMPBLPB.Clear();
@@ -501,11 +529,11 @@ void BOPAlgo_PaveFiller::PerformNewVertices
   TreatNewVertices(theMVCPB, aImages);
   //
   // 2. Add new vertices to myDS and connect indices to CPB structure
-  BOPDS_VectorOfInterfEE& aEEs = myDS->InterfEE();
+  BOPDS_VectorOfInterfEE& aEEs=myDS->InterfEE();
   BOPDS_VectorOfInterfEF& aEFs = myDS->InterfEF();
   //
   Standard_Integer i, aNb = aImages.Extent();
-  for (i = 1; i <= aNb; ++i) {
+  for (i=1; i<=aNb; ++i) {
     const TopoDS_Vertex& aV = TopoDS::Vertex(aImages.FindKey(i));
     const TopTools_ListOfShape& aLVSD = aImages.FindFromIndex(i);
     //
@@ -514,15 +542,15 @@ void BOPAlgo_PaveFiller::PerformNewVertices
     aSI.SetShape(aV);
     Standard_Integer iV = myDS->Append(aSI);
     //
-    BOPDS_ShapeInfo& aSIDS = myDS->ChangeShapeInfo(iV);
-    Bnd_Box& aBox = aSIDS.ChangeBox();
+    BOPDS_ShapeInfo& aSIDS=myDS->ChangeShapeInfo(iV);
+    Bnd_Box& aBox=aSIDS.ChangeBox();
     aBox.Add(BRep_Tool::Pnt(aV));
     aBox.SetGap(BRep_Tool::Tolerance(aV) + aTolAdd);
     //
     TopTools_ListIteratorOfListOfShape aItLS(aLVSD);
     for (; aItLS.More(); aItLS.Next()) {
       const TopoDS_Shape& aVx = aItLS.Value();
-      BOPDS_CoupleOfPaveBlocks &aCPB = theMVCPB.ChangeFromKey(aVx);
+      BOPDS_CoupleOfPaveBlocks &aCPB=theMVCPB.ChangeFromKey(aVx);
       aCPB.SetIndex(iV);
       // update interference
       Standard_Integer iX = aCPB.IndexInterf();
@@ -533,24 +561,24 @@ void BOPAlgo_PaveFiller::PerformNewVertices
   //
   // 3. Map PaveBlock/ListOfVertices to add to this PaveBlock ->aMPBLI
   BOPDS_IndexedDataMapOfPaveBlockListOfInteger aMPBLI(100, theAllocator);
-  for (i = 1; i <= aNbV; ++i) {
-    const BOPDS_CoupleOfPaveBlocks& aCPB = theMVCPB.FindFromIndex(i);
+    for (i=1; i<=aNbV; ++i) {
+      const BOPDS_CoupleOfPaveBlocks& aCPB=theMVCPB.FindFromIndex(i);
     Standard_Integer iV = aCPB.Index();
     //
     Handle(BOPDS_PaveBlock) aPB[2];
-    aCPB.PaveBlocks(aPB[0], aPB[1]);
+      aCPB.PaveBlocks(aPB[0], aPB[1]);
     for (Standard_Integer j = 0; j < 2; ++j) {
       TColStd_ListOfInteger *pLI = aMPBLI.ChangeSeek(aPB[j]);
       if (!pLI) {
         pLI = &aMPBLI(aMPBLI.Add(aPB[j], TColStd_ListOfInteger(theAllocator)));
-      }
+        }
       pLI->Append(iV);
-      //
+  //
       if (aPB[0] == aPB[1]) {
         break;
-      }
     }
   }
+    }
   //
   // 4. Compute Extra Paves and split Pave blocks by the Extra paves
   IntersectVE(aMPBLI, Standard_False);
@@ -560,14 +588,14 @@ void BOPAlgo_PaveFiller::PerformNewVertices
 //purpose  : 
 //=======================================================================
 void BOPAlgo_PaveFiller::TreatNewVertices
-  (const BOPDS_IndexedDataMapOfShapeCoupleOfPaveBlocks& theMVCPB,
+(const BOPDS_IndexedDataMapOfShapeCoupleOfPaveBlocks& theMVCPB,
    TopTools_IndexedDataMapOfShapeListOfShape& myImages)
 {
   //
   // Prepare for intersection
   TopTools_IndexedDataMapOfShapeReal aVerts;
   Standard_Integer i, aNbV = theMVCPB.Extent();
-  for (i = 1; i <= aNbV; ++i) {
+  for (i=1; i<=aNbV; ++i) {
     const TopoDS_Shape& aV = theMVCPB.FindKey(i);
     Standard_Real aTol = theMVCPB.FindFromIndex(i).Tolerance();
     aVerts.Add(aV, aTol);
@@ -581,12 +609,12 @@ void BOPAlgo_PaveFiller::TreatNewVertices
   TopTools_ListOfListOfShape::Iterator aItC(aChains);
   for (; aItC.More(); aItC.Next()) {
     const TopTools_ListOfShape& aLVSD = aItC.Value();
-    //
+  //
     TopoDS_Vertex aVNew;
     BOPTools_AlgoTools::MakeVertex(aLVSD, aVNew);
     myImages.Add(aVNew, aLVSD);
-  }
-}
+    }
+          }
 //=======================================================================
 //function : FillShrunkData
 //purpose  : 
@@ -668,7 +696,7 @@ void BOPAlgo_PaveFiller::AnalyzeShrunkData(const Handle(BOPDS_PaveBlock)& thePB,
 //purpose  : 
 //=======================================================================
 Standard_Boolean BOPAlgo_PaveFiller::ForceInterfVE(const Standard_Integer nV,
-                                                   Handle(BOPDS_PaveBlock)& aPB,
+                                       Handle(BOPDS_PaveBlock)& aPB,
                                                    TColStd_MapOfInteger& theMEdges)
 {
   Standard_Integer nE, nVx, nVSD, iFlag;
diff --git a/src/BOPAlgo/BOPAlgo_PaveFiller_5.cxx b/src/BOPAlgo/BOPAlgo_PaveFiller_5.cxx
index 7aa22d1..4238902 100644
--- a/src/BOPAlgo/BOPAlgo_PaveFiller_5.cxx
+++ b/src/BOPAlgo/BOPAlgo_PaveFiller_5.cxx
@@ -357,29 +357,29 @@ void BOPAlgo_PaveFiller::PerformEF()
           for (j=0; j<2; ++j) {
             if (bIsOnPave[j]) {
               bV[j]=CheckFacePaves(nV[j], aMIFOn, aMIFIn);
-              if (bV[j]) {
-                const TopoDS_Vertex& aV=
-                  (*(TopoDS_Vertex *)(&myDS->Shape(nV[j])));
-                //
-                Standard_Real f, l, aTolVnew, aDistPP, aTolPC, aTolV;
-                //
-                const Handle(Geom_Curve)& aCur = BRep_Tool::Curve(aE, f, l);
-                //
-                gp_Pnt aP1 = BRep_Tool::Pnt(aV);
-                gp_Pnt aP2 = aCur->Value(aT);
-                //
-                aDistPP=aP1.Distance(aP2);
-                //
-                aTolPC=Precision::PConfusion();
-                aTolV=BRep_Tool::Tolerance(aV);
-                if (aDistPP > (aTolV+aTolPC)) {
-                  aTolVnew=Max(aTolE, aDistPP);
-                  UpdateVertex(nV[j], aTolVnew);
-                }
-              }
-              else {
+              if (!bV[j])
+              {
                 bIsOnPave[j] = ForceInterfVF(nV[j], nF);
               }
+
+              const TopoDS_Vertex& aV =
+                (*(TopoDS_Vertex *)(&myDS->Shape(nV[j])));
+              //
+              Standard_Real f, l, aTolVnew, aDistPP, aTolPC, aTolV;
+              //
+              const Handle(Geom_Curve)& aCur = BRep_Tool::Curve(aE, f, l);
+              //
+              gp_Pnt aP1 = BRep_Tool::Pnt(aV);
+              gp_Pnt aP2 = aCur->Value(aT);
+              //
+              aDistPP = aP1.Distance(aP2);
+              //
+              aTolPC = Precision::PConfusion();
+              aTolV = BRep_Tool::Tolerance(aV);
+              if (aDistPP > (aTolV + aTolPC)) {
+                aTolVnew = Max(aTolE, aDistPP);
+                UpdateVertex(nV[j], aTolVnew);
+              }
             }
           }
           //
diff --git a/src/BOPAlgo/BOPAlgo_PaveFiller_6.cxx b/src/BOPAlgo/BOPAlgo_PaveFiller_6.cxx
index 66fcea7..bc3a3a5 100644
--- a/src/BOPAlgo/BOPAlgo_PaveFiller_6.cxx
+++ b/src/BOPAlgo/BOPAlgo_PaveFiller_6.cxx
@@ -554,6 +554,10 @@ void BOPAlgo_PaveFiller::MakeBlocks()
         //
         // Make Edge
         BOPTools_AlgoTools::MakeEdge (aIC, aV1, aT1, aV2, aT2, aTolR3D, aES);
+
+        if (aES.IsNull())
+          continue;
+
         //
         // check for micro edge
         if (BOPTools_AlgoTools::IsMicroEdge(aES, myContext, Standard_False)) {
diff --git a/src/BOPTest/BOPTest_LowCommands.cxx b/src/BOPTest/BOPTest_LowCommands.cxx
index b863f41..f682861 100644
--- a/src/BOPTest/BOPTest_LowCommands.cxx
+++ b/src/BOPTest/BOPTest_LowCommands.cxx
@@ -21,14 +21,18 @@
 #include <BRep_ListIteratorOfListOfCurveRepresentation.hxx>
 #include <BRep_TEdge.hxx>
 #include <BRep_Tool.hxx>
+#include <BRepAdaptor_Surface.hxx>
+#include <BRepBuilderAPI_MakePolygon.hxx>
 #include <BRepClass3d_SolidClassifier.hxx>
 #include <BRepClass_FaceClassifier.hxx>
+#include <BRepTopAdaptor_FClass2d.hxx>
+#include <CSLib_Class2d.hxx>
 #include <DBRep.hxx>
 #include <Draw.hxx>
 #include <DrawTrSurf.hxx>
+#include <Geom2d_BSplineCurve.hxx>
 #include <gp_Pnt.hxx>
 #include <gp_Pnt2d.hxx>
-#include <IntTools_FClass2d.hxx>
 #include <TCollection_AsciiString.hxx>
 #include <TopAbs_State.hxx>
 #include <TopoDS.hxx>
@@ -54,6 +58,8 @@ static  Standard_Integer bclassify   (Draw_Interpretor& , Standard_Integer , con
 static  Standard_Integer b2dclassify (Draw_Interpretor& , Standard_Integer , const char** );
 static  Standard_Integer b2dclassifx (Draw_Interpretor& , Standard_Integer , const char** );
 static  Standard_Integer bhaspc      (Draw_Interpretor& , Standard_Integer , const char** );
+static  Standard_Integer IsHole      (Draw_Interpretor&, Standard_Integer, const char**);
+static  Standard_Integer polyclassify( Draw_Interpretor&, Standard_Integer, const char** );
 
 //=======================================================================
 //function : LowCommands
@@ -68,12 +74,25 @@ static  Standard_Integer bhaspc      (Draw_Interpretor& , Standard_Integer , con
   const char* g = "BOPTest commands";
   theCommands.Add("bclassify"    , "use bclassify Solid Point [Tolerance=1.e-7]",
                   __FILE__, bclassify   , g);
-  theCommands.Add("b2dclassify"  , "use b2dclassify Face Point2d [Tol] ",
+  theCommands.Add("b2dclassify", "use b2dclassify Face Point2d "
+                  "[-t Tol3D = <FaceToler>] :\n "
+                  "Tol3D is 3D-tolerance used for check ON-status.",
                   __FILE__, b2dclassify , g);
-  theCommands.Add("b2dclassifx"  , "use b2dclassifx Face Point2d [Tol] ",
+  theCommands.Add("b2dclassifx"  , "use b2dclassifx Face Point2d "
+                  "[-t Tol3D = <FaceToler>] [-na] :\n "
+                  "Enter the command w/o arguments to obtain help.",
                   __FILE__, b2dclassifx , g);
   theCommands.Add("bhaspc"       , "use bhaspc Edge Face [do]",
                   __FILE__, bhaspc      , g);
+
+  theCommands.Add("ishole", "Use: ishole face [-t toler3D = <FaceToler>]: "
+                      "Checks if the face is hole", __FILE__, IsHole, g);
+
+  theCommands.Add("polyclassify", "Use: polyclassify [-s] -c px py -t tolU tolV "
+                  "-p px1 py1 -p px2 py2 ...:\n"
+                   "Classifies the point relatively to the polygon. "
+                   "Enter the command w/o arguments to obtain detail help.",
+                   __FILE__, polyclassify, g );
 }
 
 
@@ -87,7 +106,10 @@ Standard_Integer b2dclassifx (Draw_Interpretor& theDI,
                               const char**      theArgVec)
 {
   if (theArgNb < 3)  {
-    theDI << " use b2dclassifx Face Point2d [Tol]\n";
+    theDI << "Use b2dclassifx Face Point2d [-t Tol3D = <FaceToler>] [-na]:\n";
+    theDI << "Tol3D is 3D-tolerance used for check ON-status;\n"
+             "The option \"-na\" disables adjustment of 2d point in "
+             "the domain of periodic face.\n";
     return 1;
   }
 
@@ -100,16 +122,36 @@ Standard_Integer b2dclassifx (Draw_Interpretor& theDI,
     theDI << " Shape type must be FACE\n";
     return 1;
   }
-  TopAbs_State aState;
-  gp_Pnt2d aP (8., 9.);
+  
+  gp_Pnt2d aP;
   //
   DrawTrSurf::GetPoint2d (theArgVec[2], aP);
   const TopoDS_Face&  aF   = TopoDS::Face(aS);
-  const Standard_Real aTol = (theArgNb == 4) ? 
-    Draw::Atof (theArgVec[3]) : BRep_Tool::Tolerance (aF);
-  //
-  IntTools_FClass2d aClassifier(aF, aTol);
-  aState=aClassifier.Perform(aP);
+  
+  Standard_Real aTol3D = BRep_Tool::Tolerance(aF);
+  Standard_Boolean isReqToAdjust = Standard_True;
+
+  for (Standard_Integer aCurrArg = 3; aCurrArg < theArgNb; aCurrArg++)
+  {
+    if (theArgVec[aCurrArg][0] != '-')
+      continue;
+
+    switch (theArgVec[aCurrArg][1])
+    {
+    case 't' :
+      aTol3D = Draw::Atof(theArgVec[++aCurrArg]);
+      break;
+    case 'n' :
+      if(!strncmp(theArgVec[aCurrArg], "-na", 3))
+        isReqToAdjust = Standard_False;
+      break;
+    default:
+      break;
+    }
+  }
+
+  BRepTopAdaptor_FClass2d aClassifier(aF, aTol3D);
+  const TopAbs_State aState = aClassifier.Perform(aP, isReqToAdjust);
   PrintState (theDI, aState);
   //
   return 0;
@@ -124,7 +166,7 @@ Standard_Integer b2dclassify (Draw_Interpretor& theDI,
                               const char**      theArgVec)
 {
   if (theArgNb < 3)  {
-    theDI << " use b2dclassify Face Point2d [Tol]\n";
+    theDI << " use b2dclassify Face Point2d [-t Tol3D = <FaceToler>]\n";
     return 1;
   }
 
@@ -138,21 +180,62 @@ Standard_Integer b2dclassify (Draw_Interpretor& theDI,
     return 1;
   }
   //
-  gp_Pnt2d aP (8., 9.);
+  gp_Pnt2d aP;
   //
   DrawTrSurf::GetPoint2d (theArgVec[2], aP);
   const TopoDS_Face&  aF   = TopoDS::Face(aS);
-  const Standard_Real aTol = (theArgNb == 4) ? 
-    Draw::Atof (theArgVec[3]) : BRep_Tool::Tolerance (aF);
-  
+  Standard_Real aTol3D = BRep_Tool::Tolerance(aF);
+
+  if ((theArgNb > 3) && (theArgVec[3][0] == '-') && (theArgVec[3][1] == 't'))
+    aTol3D = Draw::Atof(theArgVec[4]);
+
   BRepClass_FaceClassifier aClassifier;
-  aClassifier.Perform(aF, aP, aTol);
+  aClassifier.Perform(aF, aP, aTol3D);
   PrintState (theDI, aClassifier.State());
   //
   return 0;
 }
 
 //=======================================================================
+//function : IsHole
+//purpose  : 
+//=======================================================================
+Standard_Integer IsHole(Draw_Interpretor& theDI,
+                        Standard_Integer  theArgNb,
+                        const char**      theArgVec)
+{
+  if (theArgNb < 2)
+  {
+    theDI << "Use: ishole face [-t Tol3D = <FaceToler>]\n";
+    return 1;
+  }
+
+  TopoDS_Face aF = TopoDS::Face(DBRep::Get(theArgVec[1]));
+
+  Standard_Real aTol = BRep_Tool::Tolerance(aF);
+  for (Standard_Integer i = 2; i < theArgNb; i++)
+  {
+    if ((theArgVec[i][0] == '-') && (theArgVec[i][1] == 't'))
+    {
+      aTol = Draw::Atof(theArgVec[++i]);
+    }
+  }
+
+  BRepTopAdaptor_FClass2d aClassifier(aF, aTol);
+  if (aClassifier.PerformInfinitePoint() == TopAbs_IN)
+  {
+    theDI << "The face is hole\n";
+  }
+  else
+  {
+    theDI << "The face is not hole\n";
+  }
+
+  return 0;
+}
+
+
+//=======================================================================
 //function : bclassify
 //purpose  : 
 //=======================================================================
@@ -188,6 +271,99 @@ Standard_Integer bclassify (Draw_Interpretor& theDI,
 }
 
 //=======================================================================
+//function : polyclassify
+//purpose  : 
+//=======================================================================
+Standard_Integer polyclassify(Draw_Interpretor& theDI,
+                              Standard_Integer  theArgNb,
+                              const char**      theArgVec)
+{
+  if(theArgNb < 9)
+  {
+    //                0          1  2  3  4  5    6    7       8
+    theDI << "Use: polyclassify -c px py -t tolU tolV -p <2D B-spline curve>\n"
+             "Classifies the point (px, py) relatively to the 2D-polygon\n"
+             "(set by \"-p\"-option) using UV-tolerances tolU and tolV.\n"
+             "This polygon is built from the poles of the 2D B-spline curve\n"
+             "(this curve must be 1st-degree-curve).\n"
+             "Such polygon can be created by \"2dpolyline\"-DRAW-command.";
+             "The algorithm will always close this polygon before classification.\n";
+    return 1;
+  }
+
+  gp_Pnt2d aClassifPnt;
+  Standard_Real aTolU = 0.0, aTolV = 0.0;
+
+  Handle(Geom2d_BSplineCurve) aCurv;
+
+  for(Standard_Integer i = 1; i < theArgNb; i++)
+  {
+    if(theArgVec[i][0] != '-')
+      continue;
+
+    switch(theArgVec[i][1])
+    {
+      case 'c':
+      {
+        const Standard_Real aX = Draw::Atof(theArgVec[++i]);
+        const Standard_Real aY = Draw::Atof(theArgVec[++i]);
+        aClassifPnt.SetCoord(aX, aY);
+        break;
+      }
+
+      case 't':
+      {
+        aTolU = Draw::Atof(theArgVec[++i]);
+        aTolV = Draw::Atof(theArgVec[++i]);
+        break;
+      }
+
+      case 'p':
+        aCurv = DrawTrSurf::GetBSplineCurve2d(theArgVec[++i]);
+        break;
+    }
+  }
+
+  if (aCurv.IsNull())
+  {
+    theDI << "Polygon is not set. Please point to 2D B-spline curve.\n";
+    return 1;
+  }
+
+  const TColgp_Array1OfPnt2d &anArrPnts = aCurv->Poles();
+  Standard_Real aUmin = RealLast(), aUmax = RealFirst();
+  Standard_Real aVmin = RealLast(), aVmax = RealFirst();
+
+  for (Standard_Integer i = anArrPnts.Lower(); i <= anArrPnts.Upper(); i++)
+  {
+    const gp_Pnt2d &aP = anArrPnts(i);
+    aUmin = Min(aUmin, aP.X());
+    aUmax = Max(aUmax, aP.X());
+    aVmin = Min(aVmin, aP.Y());
+    aVmax = Max(aVmax, aP.Y());
+  }
+
+  CSLib_Class2d aPClass(anArrPnts, aTolU, aTolV, aUmin, aVmin, aUmax, aVmax);
+  CSLib_Class2d::PolyState aState = aPClass.Classify(aClassifPnt);
+
+  theDI << "The point is ";
+  switch(aState)
+  {
+    case CSLib_Class2d::PolyOut:
+      theDI << "OUT\n";
+      break;
+    case CSLib_Class2d::PolyOn:
+      theDI << "ON\n";
+      break;
+    case CSLib_Class2d::PolyIn:
+      theDI << "IN\n";
+      break;
+  }
+
+  return 0;
+}
+
+//=======================================================================
 //function : bhaspc
 //purpose  : 
 //=======================================================================
diff --git a/src/BOPTools/BOPTools_AlgoTools.cxx b/src/BOPTools/BOPTools_AlgoTools.cxx
index b5c07f0..4c8b546 100644
--- a/src/BOPTools/BOPTools_AlgoTools.cxx
+++ b/src/BOPTools/BOPTools_AlgoTools.cxx
@@ -1657,6 +1657,10 @@ void BOPTools_AlgoTools::MakeEdge(const IntTools_Curve& theIC,
   //
   BOPTools_AlgoTools::MakeSectEdge (theIC, theV1, theT1, theV2, theT2, 
                                     theE);
+
+  if (theE.IsNull())
+    return;
+
   //
   aBB.UpdateEdge(theE, theTolR3D);
 }
diff --git a/src/BOPTools/BOPTools_AlgoTools2D.cxx b/src/BOPTools/BOPTools_AlgoTools2D.cxx
index b24667e..babb563 100644
--- a/src/BOPTools/BOPTools_AlgoTools2D.cxx
+++ b/src/BOPTools/BOPTools_AlgoTools2D.cxx
@@ -298,7 +298,7 @@ void BOPTools_AlgoTools2D::AdjustPCurveOnSurf
    Handle(Geom2d_Curve)& aC2DA)
 {
   Standard_Boolean mincond, maxcond;
-  Standard_Real UMin, UMax, VMin, VMax, aT, u2, v2, du, dv, aDelta;
+  Standard_Real UMin, UMax, VMin, VMax, aT, u2, v2, du, dv;
   Standard_Real aUPeriod;
   //
   const TopoDS_Face& aF=aBAS.Face();
@@ -307,7 +307,7 @@ void BOPTools_AlgoTools2D::AdjustPCurveOnSurf
   VMin=aBAS.FirstVParameter();
   VMax=aBAS.LastVParameter();
   //
-  aDelta=Precision::PConfusion(); 
+  const Standard_Real aDelta=Precision::PConfusion();
   
   aT =.5*(aFirst+aLast);
 
@@ -390,7 +390,7 @@ void BOPTools_AlgoTools2D::AdjustPCurveOnSurf
         if ((u > (UMin + aDelta + aUPeriod)) ||
             (u < (UMax - aDelta - aUPeriod))) {
           BRepClass_FaceClassifier aClassifier;
-          aClassifier.Perform(aF, gp_Pnt2d(u, v), aDelta);
+          aClassifier.Perform(aF, gp_Pnt2d(u, v), BRep_Tool::Tolerance(aF));
           TopAbs_State Status = aClassifier.State();
           if (Status == TopAbs_OUT) {
             du += (u > (UMin + aDelta + aUPeriod)) ? -aUPeriod : aUPeriod;
@@ -406,7 +406,7 @@ void BOPTools_AlgoTools2D::AdjustPCurveOnSurf
         if ((v > (VMin + aDelta + aVPeriod)) ||
             (v < (VMax - aDelta - aVPeriod))) {
           BRepClass_FaceClassifier aClassifier;
-          aClassifier.Perform(aF, gp_Pnt2d(u, v), aDelta);
+          aClassifier.Perform(aF, gp_Pnt2d(u, v), BRep_Tool::Tolerance(aF));
           TopAbs_State Status = aClassifier.State();
           if (Status == TopAbs_OUT) {
             dv += (v > (VMin + aDelta + aVPeriod)) ? -aVPeriod : aVPeriod;
diff --git a/src/BOPTools/BOPTools_AlgoTools_2.cxx b/src/BOPTools/BOPTools_AlgoTools_2.cxx
index 9ed2175..98e8511 100644
--- a/src/BOPTools/BOPTools_AlgoTools_2.cxx
+++ b/src/BOPTools/BOPTools_AlgoTools_2.cxx
@@ -122,6 +122,12 @@ void BOPTools_AlgoTools::MakeSectEdge(const IntTools_Curve& aIC,
   
   BRepBuilderAPI_MakeEdge aMakeEdge(aC, aV1, aV2, aP1, aP2);
   
+  if (!aMakeEdge.IsDone())
+  {
+    aNewEdge.Nullify();
+    return;
+  }
+
   const TopoDS_Edge& aE=TopoDS::Edge(aMakeEdge.Shape());
   //
   // Range must be as it was !
diff --git a/src/BRep/BRep_Tool.hxx b/src/BRep/BRep_Tool.hxx
index ed66f84..9430dea 100644
--- a/src/BRep/BRep_Tool.hxx
+++ b/src/BRep/BRep_Tool.hxx
@@ -218,6 +218,8 @@ public:
   Standard_EXPORT static void UVPoints (const TopoDS_Edge& E, const Handle(Geom_Surface)& S, const TopLoc_Location& L, gp_Pnt2d& PFirst, gp_Pnt2d& PLast);
   
   //! Gets the UV locations of the extremities of the edge.
+  //! It does not take into account the orientation of E and F
+  //! (i.e. returns first and last points of CurveOnSurface)
   Standard_EXPORT static void UVPoints (const TopoDS_Edge& E, const TopoDS_Face& F, gp_Pnt2d& PFirst, gp_Pnt2d& PLast);
   
   //! Sets the UV locations of the extremities of the edge.
diff --git a/src/BRep/FILES b/src/BRep/FILES
index c180c20..2c465ea 100644
--- a/src/BRep/FILES
+++ b/src/BRep/FILES
@@ -48,8 +48,8 @@ BRep_TEdge.lxx
 BRep_TFace.cxx
 BRep_TFace.hxx
 BRep_TFace.lxx
-BRep_Tool.cxx
-BRep_Tool.hxx
 BRep_TVertex.cxx
 BRep_TVertex.hxx
 BRep_TVertex.lxx
+BRep_Tool.cxx
+BRep_Tool.hxx
diff --git a/src/BRepAlgo/BRepAlgo_FaceRestrictor.cxx b/src/BRepAlgo/BRepAlgo_FaceRestrictor.cxx
index f01b28b..a89605f 100644
--- a/src/BRepAlgo/BRepAlgo_FaceRestrictor.cxx
+++ b/src/BRepAlgo/BRepAlgo_FaceRestrictor.cxx
@@ -250,8 +250,7 @@ static Standard_Boolean IsClosed (const TopoDS_Wire& W)
 //=======================================================================
 
 static Standard_Boolean IsInside(const TopoDS_Wire&       wir,
-                                 const TopoDS_Face&       F,
-                                 BRepTopAdaptor_FClass2d& /*FClass2d*/)
+                                 const TopoDS_Face&       F)
 {
   TopExp_Explorer exp;
   exp.Init(wir,TopAbs_EDGE);
@@ -277,9 +276,9 @@ static Standard_Boolean IsInside(const TopoDS_Wire&       wir,
     }
 
     gp_Pnt2d pt2d(C2d->Value(prm));
-    BRepTopAdaptor_FClass2d FClass2d(F,Precision::PConfusion());
+    BRepTopAdaptor_FClass2d FClass2d(F,Precision::Confusion());
     TopAbs_State st2=FClass2d.Perform(pt2d,Standard_False);
-    return(st2 == TopAbs_IN);     
+    return(st2 == TopAbs_IN);
   }
   return Standard_False;
 }
@@ -393,7 +392,7 @@ void BRepAlgo_FaceRestrictor::PerformWithCorrection()
     B.Add(NF,W);
     
     if (IsClosed(W)) {  
-      BRepTopAdaptor_FClass2d FClass2d(NF,Precision::PConfusion());
+      BRepTopAdaptor_FClass2d FClass2d(NF,Precision::Confusion());
       if(FClass2d.PerformInfinitePoint() != TopAbs_OUT) { 
         W.Reverse();
       }
@@ -416,10 +415,9 @@ void BRepAlgo_FaceRestrictor::PerformWithCorrection()
       NF.Orientation(TopAbs_FORWARD);
       B.Add(NF,W1);
       
-      BRepTopAdaptor_FClass2d FClass2d(NF,Precision::PConfusion());
       while (it2.More()) {
         const TopoDS_Wire& W2 = TopoDS::Wire(it2.Value());
-        if (!W1.IsSame(W2) && IsInside (W2,NF,FClass2d)) {
+        if (!W1.IsSame(W2) && IsInside (W2,NF)) {
           Store (W2,W1,keyIsIn,keyContains);
         } 
         it2.Next();
diff --git a/src/BRepAlgo/BRepAlgo_NormalProjection.cxx b/src/BRepAlgo/BRepAlgo_NormalProjection.cxx
index 319f0da..af045b2 100644
--- a/src/BRepAlgo/BRepAlgo_NormalProjection.cxx
+++ b/src/BRepAlgo/BRepAlgo_NormalProjection.cxx
@@ -495,8 +495,8 @@ void BRepAlgo_NormalProjection::SetDefaultParams()
               }
               else {
                 // if the common operation has failed, try to classify the part
-	         BRepTopAdaptor_FClass2d classifier(TopoDS::Face(Faces->Value(j)),
-			  		  	    Precision::Confusion());
+                 BRepTopAdaptor_FClass2d classifier(TopoDS::Face(Faces->Value(j)),
+                                                    Precision::Confusion());
 	         gp_Pnt2d Puv;
 	         Standard_Real f = PCur2d->FirstParameter();
 	         Standard_Real l = PCur2d->LastParameter();
@@ -517,8 +517,8 @@ void BRepAlgo_NormalProjection::SetDefaultParams()
                  cout << " BooleanOperations : no solution " << endl;
 #endif
 
-	      BRepTopAdaptor_FClass2d classifier(TopoDS::Face(Faces->Value(j)),
-			  		  	 Precision::Confusion());
+              BRepTopAdaptor_FClass2d classifier(TopoDS::Face(Faces->Value(j)),
+                                                 Precision::Confusion());
 	      gp_Pnt2d Puv;
 	      Standard_Real f = PCur2d->FirstParameter();
 	      Standard_Real l = PCur2d->LastParameter();
diff --git a/src/BRepBlend/BRepBlend_CSWalking.hxx b/src/BRepBlend/BRepBlend_CSWalking.hxx
index 27cbe6d..5f7798b 100644
--- a/src/BRepBlend/BRepBlend_CSWalking.hxx
+++ b/src/BRepBlend/BRepBlend_CSWalking.hxx
@@ -97,8 +97,8 @@ private:
   Handle(BRepBlend_Line) line;
   Handle(Adaptor3d_HSurface) surf;
   Handle(Adaptor3d_HCurve) curv;
-  Handle(Adaptor3d_TopolTool) domain;
-  Standard_Real tolesp;
+  Handle(Adaptor3d_TopolTool) myDomain;
+  Standard_Real my3DTolEsp;
   Standard_Real tolgui;
   Standard_Real pasmax;
   Standard_Real fleche;
diff --git a/src/BRepBlend/BRepBlend_RstRstLineBuilder.cxx b/src/BRepBlend/BRepBlend_RstRstLineBuilder.cxx
index a291aa3..e92f3ed 100644
--- a/src/BRepBlend/BRepBlend_RstRstLineBuilder.cxx
+++ b/src/BRepBlend/BRepBlend_RstRstLineBuilder.cxx
@@ -174,8 +174,8 @@ BRepBlend_RstRstLineBuilder::BRepBlend_RstRstLineBuilder
  const Handle(Adaptor3d_HSurface)&  Surf2,
  const Handle(Adaptor2d_HCurve2d)&  Rst2,
  const Handle(Adaptor3d_TopolTool)& Domain2):
- sol(1,2), surf1(Surf1), domain1(Domain1),
- surf2(Surf2), domain2(Domain2), rst1(Rst1), rst2(Rst2)
+ sol(1,2), surf1(Surf1), myDomain1(Domain1),
+ surf2(Surf2), myDomain2(Domain2), rst1(Rst1), rst2(Rst2)
 {
 }
 
@@ -194,7 +194,7 @@ void BRepBlend_RstRstLineBuilder::Perform(Blend_RstRstFunction&   Func,
 					  const Standard_Real     MaxStep,
 					  const Standard_Real     TolGuide,
 					  const math_Vector&      ParDep,
-					  const Standard_Real     Tolesp,
+					  const Standard_Real     the3DTolEsp,
 					  const Standard_Real     Fleche,
 					  const Standard_Boolean  Appro) 
 {
@@ -202,7 +202,7 @@ void BRepBlend_RstRstLineBuilder::Perform(Blend_RstRstFunction&   Func,
   iscomplete = Standard_False;
   comptra    = Standard_False;
   line       = new BRepBlend_Line();
-  tolesp     = Abs(Tolesp);
+  my3DTolEsp = Abs(the3DTolEsp);
   tolgui     = Abs(TolGuide);
   fleche     = Abs(Fleche);
   rebrou     = Standard_False;
@@ -223,10 +223,10 @@ void BRepBlend_RstRstLineBuilder::Perform(Blend_RstRstFunction&   Func,
   if (Appro) {
     TopAbs_State siturst1, siturst2;
     Blend_DecrochStatus decroch;
-    math_Vector tolerance(1, 2), infbound(1, 2), supbound(1, 2);
-    Func.GetTolerance(tolerance, tolesp);
+    math_Vector aVTol2D(1, 2), infbound(1, 2), supbound(1, 2);
+    Func.GetTolerance(aVTol2D, my3DTolEsp);
     Func.GetBounds(infbound, supbound);
-    math_FunctionSetRoot rsnld(Func, tolerance, 30);
+    math_FunctionSetRoot rsnld(Func, aVTol2D, 30);
     
     rsnld.Perform(Func, ParDep, infbound, supbound);
     
@@ -256,10 +256,8 @@ void BRepBlend_RstRstLineBuilder::Perform(Blend_RstRstFunction&   Func,
   Standard_Real U, V;
   U = previousP.ParameterOnC1();
   V = previousP.ParameterOnC2();
-  BRepBlend_Extremity ptf1 (previousP.PointOnC1(),
-			    U, previousP.Parameter(),tolesp);
-  BRepBlend_Extremity ptf2 (previousP.PointOnC2(),
-			    V, previousP.Parameter(),tolesp);
+  BRepBlend_Extremity ptf1(previousP.PointOnC1(), U, previousP.Parameter(), my3DTolEsp);
+  BRepBlend_Extremity ptf2(previousP.PointOnC2(), V, previousP.Parameter(), my3DTolEsp);
   if (!previousP.IsTangencyPoint()) {
     ptf1.SetTangent(previousP.TangentOnC1());
     ptf2.SetTangent(previousP.TangentOnC2());
@@ -290,7 +288,7 @@ Standard_Boolean BRepBlend_RstRstLineBuilder::PerformFirstSection
  const Standard_Real     Pdep,
  const Standard_Real     Pmax,
  const math_Vector&      ParDep,
- const Standard_Real     Tolesp,
+ const Standard_Real     the3DTolEsp,
  const Standard_Real     TolGuide,
  const Standard_Boolean  RecRst1,
  const Standard_Boolean  RecP1,
@@ -303,7 +301,7 @@ Standard_Boolean BRepBlend_RstRstLineBuilder::PerformFirstSection
   iscomplete = Standard_False;
   comptra    = Standard_False;
   line       = new BRepBlend_Line();
-  tolesp     = Abs(Tolesp);
+  my3DTolEsp = Abs(the3DTolEsp);
   tolgui     = Abs(TolGuide);
   rebrou     = Standard_False;
   
@@ -318,7 +316,7 @@ Standard_Boolean BRepBlend_RstRstLineBuilder::PerformFirstSection
   Standard_Real wp1, wp2, wrst1, wrst2;
   Blend_Status State = Blend_OnRst12;
   Standard_Real trst11 = 0., trst12 = 0., trst21 = 0., trst22 = 0.;
-  math_Vector infbound(1, 2), supbound(1, 2), tolerance(1, 2);
+  math_Vector infbound(1, 2), supbound(1, 2), aVTol2D(1, 2);
   math_Vector solinvp1(1, 2), solinvp2(1, 2), solinvrst1(1, 3), solinvrst2(1, 3);
   Handle(Adaptor3d_HVertex) Vtxp1, Vtxp2, Vtxrst1, Vtxrst2, Vtxc;
   Standard_Boolean IsVtxp1 = 0, IsVtxp2 = 0, IsVtxrst1 = 0, IsVtxrst2 = 0;
@@ -326,10 +324,10 @@ Standard_Boolean BRepBlend_RstRstLineBuilder::PerformFirstSection
   wp1   = wp2 = wrst1 = wrst2 = Pmax;
   param = Pdep;
   Func.Set(param);
-  Func.GetTolerance(tolerance, tolesp);
+  Func.GetTolerance(aVTol2D, my3DTolEsp);
   Func.GetBounds(infbound, supbound);
 
-  math_FunctionSetRoot rsnld(Func, tolerance, 30);
+  math_FunctionSetRoot rsnld(Func, aVTol2D, 30);
   rsnld.Perform(Func, ParDep, infbound, supbound);
   if (!rsnld.IsDone()) return Standard_False;
   rsnld.Root(sol);
@@ -564,7 +562,7 @@ void BRepBlend_RstRstLineBuilder::InternalPerform(Blend_RstRstFunction&   Func,
   Standard_Boolean Arrive, recadp1, recadp2, recadrst1, recadrst2, echecrecad;
   Standard_Real wp1, wp2, wrst1, wrst2;
   math_Vector infbound(1, 2), supbound(1, 2);
-  math_Vector parinit(1, 2), tolerance(1, 2);
+  math_Vector parinit(1, 2), aVtol2D(1, 2);
   math_Vector solinvp1(1, 2),  solinvp2(1, 2), solinvrst1(1, 3), solinvrst2(1, 3);
   Handle(Adaptor3d_HVertex) Vtxp1, Vtxp2, Vtxrst1, Vtxrst2;
   Standard_Boolean IsVtxp1 = 0, IsVtxp2 = 0, IsVtxrst1 = 0, IsVtxrst2 = 0;
@@ -572,10 +570,10 @@ void BRepBlend_RstRstLineBuilder::InternalPerform(Blend_RstRstFunction&   Func,
 
   //IntSurf_Transition Tline, Tarc;
 
-  Func.GetTolerance(tolerance, tolesp);
+  Func.GetTolerance(aVtol2D, my3DTolEsp);
   Func.GetBounds(infbound, supbound);
 
-  math_FunctionSetRoot rsnld(Func, tolerance, 30);
+  math_FunctionSetRoot rsnld(Func, aVtol2D, 30);
   parinit = sol;
 
   Arrive = Standard_False;
@@ -851,9 +849,8 @@ void BRepBlend_RstRstLineBuilder::InternalPerform(Blend_RstRstFunction&   Func,
 	
 	if (param == Bound) {
 	  Arrive = Standard_True;
-	  Extrst1.SetValue(previousP.PointOnC1(),
-			   previousP.ParameterOnC1(),
-			   previousP.Parameter(), tolesp);
+	  Extrst1.SetValue(previousP.PointOnC1(), previousP.ParameterOnC1(),
+                           previousP.Parameter(), my3DTolEsp);
 	  MakeExtremity(Extrst2, Standard_False, rst2, sol(2), IsVtxrst2, Vtxrst2);
 	  // Show that end is on Bound.
 	}
@@ -870,12 +867,10 @@ void BRepBlend_RstRstLineBuilder::InternalPerform(Blend_RstRstFunction&   Func,
       {
 	stepw = stepw / 2.;
 	if (Abs(stepw) < tolgui) {
-	  Extrst1.SetValue(previousP.PointOnC1(),
-			   previousP.ParameterOnC1(),
-			   previousP.Parameter(), tolesp);
-	  Extrst2.SetValue(previousP.PointOnC2(),
-			   previousP.ParameterOnC2(),
-			   previousP.Parameter(), tolesp);
+	  Extrst1.SetValue(previousP.PointOnC1(), previousP.ParameterOnC1(),
+                           previousP.Parameter(), my3DTolEsp);
+	  Extrst2.SetValue(previousP.PointOnC2(), previousP.ParameterOnC2(),
+                           previousP.Parameter(), my3DTolEsp);
 	  Arrive = Standard_True;
 #ifdef OCCT_DEBUG
 	  if (line->NbPoints()>=2) {
@@ -910,9 +905,8 @@ void BRepBlend_RstRstLineBuilder::InternalPerform(Blend_RstRstFunction&   Func,
 	stepw   = Min(1.5 * stepw, pasmax);
 	if (param == Bound) {
 	  Arrive = Standard_True;
-	  Extrst1.SetValue(previousP.PointOnC1(),
-			   previousP.ParameterOnC1(),
-			   previousP.Parameter(), tolesp);
+	  Extrst1.SetValue(previousP.PointOnC1(), previousP.ParameterOnC1(),
+                           previousP.Parameter(), my3DTolEsp);
 	  MakeExtremity(Extrst2, Standard_False, rst2, sol(2), IsVtxrst2, Vtxrst2);
 	  // Indicate that end is on Bound.
 	}
@@ -990,12 +984,10 @@ void BRepBlend_RstRstLineBuilder::InternalPerform(Blend_RstRstFunction&   Func,
 #ifdef OCCT_DEBUG
 	cout << " Mixed points in the processing" << endl;
 #endif
-	Extrst1.SetValue(previousP.PointOnC1(),
-			 previousP.ParameterOnC1(),
-			 previousP.Parameter(), tolesp);
-	Extrst2.SetValue(previousP.PointOnC2(),
-			 previousP.ParameterOnC2(),
-			 previousP.Parameter(), tolesp);
+	Extrst1.SetValue(previousP.PointOnC1(), previousP.ParameterOnC1(),
+                         previousP.Parameter(), my3DTolEsp);
+	Extrst2.SetValue(previousP.PointOnC2(), previousP.ParameterOnC2(),
+                         previousP.Parameter(), my3DTolEsp);
 	Arrive = Standard_True;
       }
       break;
@@ -1027,15 +1019,15 @@ Standard_Boolean BRepBlend_RstRstLineBuilder::Recadre1(Blend_RstRstFunction&
 						       Standard_Boolean&        IsVtx,
 						       Handle(Adaptor3d_HVertex)& Vtx) 
 {
-  math_Vector toler(1, 3), infb(1, 3), supb(1, 3);
-  Finv.GetTolerance(toler, tolesp);
+  math_Vector aVTol2D(1, 3), infb(1, 3), supb(1, 3);
+  Finv.GetTolerance(aVTol2D, my3DTolEsp);
   Finv.GetBounds(infb, supb);
   Solinv(1) = param;
   Solinv(2) = sol(2);
   Solinv(3) = sol(1);
  
   // The point where contact is not lost is found
-  math_FunctionSetRoot rsnld(Finv, toler, 30);
+  math_FunctionSetRoot rsnld(Finv, aVTol2D, 30);
   rsnld.Perform(Finv, Solinv, infb, supb);
   if (!rsnld.IsDone()) {
 #ifdef OCCT_DEBUG
@@ -1048,40 +1040,41 @@ Standard_Boolean BRepBlend_RstRstLineBuilder::Recadre1(Blend_RstRstFunction&
 
   // It is necessary to check if the function value meets the
   // second restriction
-  if (Finv.IsSolution(Solinv, tolesp)) {
+  if (Finv.IsSolution(Solinv, my3DTolEsp)) {
     Standard_Real w = Solinv(2);
-    if(w < rst2->FirstParameter() - toler(2)||
-       w > rst2->LastParameter() + toler(2)){
+    if ((aVTol2D(2) < (rst2->FirstParameter() - w)) ||
+      ((w - rst2->LastParameter()) > aVTol2D(2)))
+    {
       return Standard_False;
     }
  
     // it is checked if it is on a Vertex
-    domain1->Initialize(rst1);
-    domain1->InitVertexIterator();
-    IsVtx = !domain1->MoreVertex();
+    myDomain1->Initialize(rst1);
+    myDomain1->InitVertexIterator();
+    IsVtx = !myDomain1->MoreVertex();
     while (!IsVtx) {
-      Vtx = domain1->Vertex();
+      Vtx = myDomain1->Vertex();
       if (Abs(BRepBlend_BlendTool::Parameter(Vtx, rst1)-Solinv(3)) <=
 	  BRepBlend_BlendTool::Tolerance(Vtx, rst1)) {
 	IsVtx = Standard_True;
       }
       else {
-	domain1->NextVertex();
-	IsVtx = !domain1->MoreVertex();
+	myDomain1->NextVertex();
+	IsVtx = !myDomain1->MoreVertex();
       }
     }
-    if (!domain1->MoreVertex()) {
+    if (!myDomain1->MoreVertex()) {
       IsVtx = Standard_False;
     }
     // The section is recalculated by direct solution, otherwise return 
     // incoherences between the parameter and the ground caused by yawn.
 
     math_Vector infbound(1, 2), supbound(1, 2);
-    math_Vector parinit(1, 2), tolerance(1, 2);
-    Func.GetTolerance(tolerance, tolesp);
+    math_Vector parinit(1, 2), aVTol2D(1, 2);
+    Func.GetTolerance(aVTol2D, my3DTolEsp);
     Func.GetBounds(infbound, supbound);
 
-    math_FunctionSetRoot rsnld2(Func, tolerance, 30);
+    math_FunctionSetRoot rsnld2(Func, aVTol2D, 30);
     parinit(1) = Solinv(3);
     parinit(2) = Solinv(2);
     Func.Set(Solinv(1));
@@ -1110,14 +1103,14 @@ Standard_Boolean BRepBlend_RstRstLineBuilder::Recadre2(Blend_RstRstFunction&
 						       Standard_Boolean&        IsVtx,
 						       Handle(Adaptor3d_HVertex)& Vtx) 
 {
-  math_Vector toler(1, 3), infb(1, 3), supb(1, 3);
-  Finv.GetTolerance(toler, tolesp);
+  math_Vector aVTol2D(1, 3), infb(1, 3), supb(1, 3);
+  Finv.GetTolerance(aVTol2D, my3DTolEsp);
   Finv.GetBounds(infb, supb);
   Solinv(1) = param;
   Solinv(2) = sol(1);
   Solinv(3) = sol(2);
  
-  math_FunctionSetRoot rsnld(Finv, toler, 30);
+  math_FunctionSetRoot rsnld(Finv, aVTol2D, 30);
   rsnld.Perform(Finv, Solinv, infb, supb);
   if (!rsnld.IsDone()) {
 #ifdef OCCT_DEBUG
@@ -1129,39 +1122,40 @@ Standard_Boolean BRepBlend_RstRstLineBuilder::Recadre2(Blend_RstRstFunction&
   rsnld.Root(Solinv);
 
   // It is necessary to check the value of the function
-  if (Finv.IsSolution(Solinv, tolesp)) {
+  if (Finv.IsSolution(Solinv, my3DTolEsp)) {
     Standard_Real w = Solinv(2);
-    if(w < rst1->FirstParameter() - toler(2)||
-       w > rst1->LastParameter() + toler(2)){
+    if ((aVTol2D(2) < (rst1->FirstParameter() - w)) ||
+        ((w - rst1->LastParameter()) > aVTol2D(2)))
+    {
       return Standard_False;
     }
  
-    domain2->Initialize(rst2);
-    domain2->InitVertexIterator();
-    IsVtx = !domain2->MoreVertex();
+    myDomain2->Initialize(rst2);
+    myDomain2->InitVertexIterator();
+    IsVtx = !myDomain2->MoreVertex();
     while (!IsVtx) {
-      Vtx = domain2->Vertex();
+      Vtx = myDomain2->Vertex();
       if (Abs(BRepBlend_BlendTool::Parameter(Vtx, rst2)-Solinv(3)) <=
 	  BRepBlend_BlendTool::Tolerance(Vtx, rst2)) {
 	IsVtx = Standard_True;
       }
       else {
-	domain2->NextVertex();
-	IsVtx = !domain2->MoreVertex();
+	myDomain2->NextVertex();
+	IsVtx = !myDomain2->MoreVertex();
       }
     }
-    if (!domain2->MoreVertex()) {
+    if (!myDomain2->MoreVertex()) {
       IsVtx = Standard_False;
     }
     // The section is recalculated by direct solution, otherwise return 
     // incoherences between the parameter and the ground caused by yawn.
    
     math_Vector infbound(1, 2), supbound(1, 2);
-    math_Vector parinit(1,2), tolerance(1,2);
-    Func.GetTolerance(tolerance, tolesp);
+    math_Vector parinit(1,2), aVTol2D(1,2);
+    Func.GetTolerance(aVTol2D, my3DTolEsp);
     Func.GetBounds(infbound, supbound);
 
-    math_FunctionSetRoot rsnld2(Func, tolerance, 30);
+    math_FunctionSetRoot rsnld2(Func, aVTol2D, 30);
     parinit(1) = Solinv(2);
     parinit(2) = Solinv(3);
     Func.Set(Solinv(1));
@@ -1197,13 +1191,13 @@ Standard_Boolean BRepBlend_RstRstLineBuilder::Recadre1(Blend_CurvPointFuncInv&
   gp_Pnt thepoint = surf1->Value(p2drst1.X(), p2drst1.Y());
 
   FinvP.Set(thepoint);
-  math_Vector toler(1,2), infb(1, 2), supb(1, 2);
-  FinvP.GetTolerance(toler, tolesp);
+  math_Vector aVTol2D(1,2), infb(1, 2), supb(1, 2);
+  FinvP.GetTolerance(aVTol2D, my3DTolEsp);
   FinvP.GetBounds(infb, supb);
   Solinv(1) = param;
   Solinv(2) = sol(2);
 
-  math_FunctionSetRoot rsnld(FinvP, toler, 30);
+  math_FunctionSetRoot rsnld(FinvP, aVTol2D, 30);
   rsnld.Perform(FinvP, Solinv, infb, supb);
   if (!rsnld.IsDone()) {
 #ifdef OCCT_DEBUG
@@ -1213,27 +1207,27 @@ Standard_Boolean BRepBlend_RstRstLineBuilder::Recadre1(Blend_CurvPointFuncInv&
   }
   rsnld.Root(Solinv);
   
-  if(FinvP.IsSolution(Solinv, tolesp)){
+  if (FinvP.IsSolution(Solinv, my3DTolEsp)){
     gp_Pnt2d p2drst2  = rst2->Value(Solinv(2));
-    TopAbs_State situ = domain2->Classify(p2drst2, toler(2), 0);
+    TopAbs_State situ = myDomain2->Classify(p2drst2, my3DTolEsp, Standard_False);
     if ((situ != TopAbs_IN) && (situ != TopAbs_ON)) {
       return Standard_False;
     }
-    domain1->Initialize(rst1);
-    domain1->InitVertexIterator();
-    IsVtx = !domain1->MoreVertex();
+    myDomain1->Initialize(rst1);
+    myDomain1->InitVertexIterator();
+    IsVtx = !myDomain1->MoreVertex();
     while (!IsVtx) {
-      Vtx = domain1->Vertex();
+      Vtx = myDomain1->Vertex();
       if (Abs(BRepBlend_BlendTool::Parameter(Vtx, rst1) - upoint) <=
 	  BRepBlend_BlendTool::Tolerance(Vtx, rst1)) {
 	IsVtx = Standard_True;
       }
       else {
-	domain1->NextVertex();
-	IsVtx = !domain1->MoreVertex();
+	myDomain1->NextVertex();
+	IsVtx = !myDomain1->MoreVertex();
       }
     }
-    if (!domain1->MoreVertex()) {
+    if (!myDomain1->MoreVertex()) {
       IsVtx = Standard_False;
     }
     return Standard_True;
@@ -1265,13 +1259,13 @@ Standard_Boolean BRepBlend_RstRstLineBuilder::Recadre2(Blend_CurvPointFuncInv&
   gp_Pnt thepoint = surf2->Value(p2drst2.X(), p2drst2.Y());
 
   FinvP.Set(thepoint);
-  math_Vector toler(1,2), infb(1, 2), supb(1, 2);
-  FinvP.GetTolerance(toler, tolesp);
+  math_Vector aVTol2D(1,2), infb(1, 2), supb(1, 2);
+  FinvP.GetTolerance(aVTol2D, my3DTolEsp);
   FinvP.GetBounds(infb, supb);
   Solinv(1) = param;
   Solinv(2) = sol(1);
 
-  math_FunctionSetRoot rsnld(FinvP, toler, 30);
+  math_FunctionSetRoot rsnld(FinvP, aVTol2D, 30);
   rsnld.Perform(FinvP, Solinv, infb, supb);
   if (!rsnld.IsDone()) {
 #ifdef OCCT_DEBUG
@@ -1281,27 +1275,27 @@ Standard_Boolean BRepBlend_RstRstLineBuilder::Recadre2(Blend_CurvPointFuncInv&
   }
   rsnld.Root(Solinv);
   
-  if(FinvP.IsSolution(Solinv, tolesp)){
+  if (FinvP.IsSolution(Solinv, my3DTolEsp)){
     gp_Pnt2d p2drst1  = rst1->Value(Solinv(2));
-    TopAbs_State situ = domain1->Classify(p2drst1, toler(2), 0);
+    TopAbs_State situ = myDomain1->Classify(p2drst1, my3DTolEsp, Standard_False);
     if ((situ != TopAbs_IN) && (situ != TopAbs_ON)) {
       return Standard_False;
     }
-    domain2->Initialize(rst2);
-    domain2->InitVertexIterator();
-    IsVtx = !domain2->MoreVertex();
+    myDomain2->Initialize(rst2);
+    myDomain2->InitVertexIterator();
+    IsVtx = !myDomain2->MoreVertex();
     while (!IsVtx) {
-      Vtx = domain2->Vertex();
+      Vtx = myDomain2->Vertex();
       if (Abs(BRepBlend_BlendTool::Parameter(Vtx, rst2) - vpoint) <=
 	  BRepBlend_BlendTool::Tolerance(Vtx, rst2)) {
 	IsVtx = Standard_True;
       }
       else {
-	domain2->NextVertex();
-	IsVtx = !domain2->MoreVertex();
+        myDomain2->NextVertex();
+        IsVtx = !myDomain2->MoreVertex();
       }
     }
-    if (!domain2->MoreVertex()) {
+    if (!myDomain2->MoreVertex()) {
       IsVtx = Standard_False;
     }
     return Standard_True;
@@ -1377,18 +1371,17 @@ void BRepBlend_RstRstLineBuilder::MakeExtremity(BRepBlend_Extremity&
   if (OnFirst) {
     Extrem.SetValue(previousP.PointOnC1(),
 		    sol(1),
-		    previousP.Parameter(), tolesp);
+		    previousP.Parameter(), my3DTolEsp);
     if (!previousP.IsTangencyPoint()) 
       Extrem.SetTangent(previousP.TangentOnC1());
-    Iter = domain1;
+    Iter = myDomain1;
   }
   else {
-    Extrem.SetValue(previousP.PointOnC2(),
-		    sol(2),
-		    previousP.Parameter(), tolesp);
+    Extrem.SetValue(previousP.PointOnC2(), sol(2),
+                    previousP.Parameter(), my3DTolEsp);
     if (!previousP.IsTangencyPoint()) 
       Extrem.SetTangent(previousP.TangentOnC1());
-    Iter = domain2;
+    Iter = myDomain2;
   }
   
   Iter->Init();
@@ -1413,8 +1406,8 @@ void BRepBlend_RstRstLineBuilder::MakeExtremity(BRepBlend_Extremity&
 	}
       }
       else {
-	Transition(OnFirst, arc, Param, Tline, Tarc);
-	Extrem.AddArc(arc, Param, Tline, Tarc);
+        Transition(OnFirst, arc, Param, Tline, Tarc);
+        Extrem.AddArc(arc, Param, Tline, Tarc);
       }
       Iter->Next();
     }
@@ -1452,12 +1445,12 @@ Blend_Status BRepBlend_RstRstLineBuilder::CheckDeflectionOnRst1(const Blend_Poin
   Norme = Corde.SquareMagnitude();
   if (!prevpointistangent) prevNorme = prevTg.SquareMagnitude();
 
-  if (Norme <= tolesp * tolesp) {
+  if (Norme <= my3DTolEsp * my3DTolEsp) {
     // it can be necessary to force the same point
     return Blend_SamePoints;
   }
   if(!prevpointistangent){
-    if (prevNorme <= tolesp * tolesp) {
+    if (prevNorme <= my3DTolEsp * my3DTolEsp) {
       return Blend_SamePoints;
     }
     Cosi = sens * Corde * prevTg;
@@ -1529,12 +1522,12 @@ Blend_Status BRepBlend_RstRstLineBuilder::CheckDeflectionOnRst2(const Blend_Poin
   Norme = Corde.SquareMagnitude();
   if (!prevpointistangent) prevNorme = prevTg.SquareMagnitude();
 
-  if (Norme <= tolesp * tolesp){
+  if (Norme <= my3DTolEsp * my3DTolEsp){
     // it can be necessary to force the same point
     return Blend_SamePoints;
   }
   if (!prevpointistangent) {
-    if (prevNorme <= tolesp * tolesp) {
+    if (prevNorme <= my3DTolEsp * my3DTolEsp) {
       return Blend_SamePoints;
     }
     Cosi = sens * Corde * prevTg;
@@ -1596,7 +1589,7 @@ Blend_Status BRepBlend_RstRstLineBuilder::TestArret(Blend_RstRstFunction& Func,
   IntSurf_TypeTrans trarst1 = IntSurf_Undecided, trarst2 = IntSurf_Undecided;
   Blend_Point curpoint;
 
-  if (Func.IsSolution(sol, tolesp)) {
+  if (Func.IsSolution(sol, my3DTolEsp)) {
     Standard_Boolean curpointistangent = Func.IsTangencyPoint();
     ptrst1   = Func.PointOnRst1();
     ptrst2   = Func.PointOnRst2();
@@ -1641,9 +1634,9 @@ Blend_Status BRepBlend_RstRstLineBuilder::TestArret(Blend_RstRstFunction& Func,
       gp_Vec2d tg2drstref;
       rst1->D1(sol(1), p2drstref, tg2drstref);
       Standard_Real testra = tg2drst1.Dot(tg2drstref);
-      TopAbs_Orientation Or = domain1->Orientation(rst1);
+      TopAbs_Orientation Or = myDomain1->Orientation(rst1);
 
-      if (Abs(testra) > tolesp) {
+      if (Abs(testra) > my3DTolEsp) {
 	if (testra < 0.) {
           trarst1 = ConvOrToTra(TopAbs::Reverse(Or));
 	}
@@ -1654,8 +1647,8 @@ Blend_Status BRepBlend_RstRstLineBuilder::TestArret(Blend_RstRstFunction& Func,
 	rst2->D1(sol(2), p2drstref, tg2drstref);
 	testra = tg2drst2.Dot(tg2drstref);
 
-	Or = domain2->Orientation(rst2);
-	if (Abs(testra) > tolesp) {
+	Or = myDomain2->Orientation(rst2);
+        if (Abs(testra) > my3DTolEsp) {
 	  if (testra < 0.) {
 	    trarst2 = ConvOrToTra(TopAbs::Reverse(Or));
 	  }
@@ -1703,13 +1696,14 @@ Standard_Boolean BRepBlend_RstRstLineBuilder::CheckInside(Blend_RstRstFunction&
 							  Blend_DecrochStatus &  Decroch)
 {
 //  Standard_Boolean inside = Standard_True;
-  math_Vector tolerance(1, 2);
-  Func.GetTolerance(tolerance, tolesp);
+  math_Vector aVToler2D(1, 2);
+  Func.GetTolerance(aVToler2D, my3DTolEsp);
 
   //face pcurve 1.
   Standard_Real v = sol(1);
-  if(v < rst1->FirstParameter() - tolerance(2)||
-     v > rst1->LastParameter() + tolerance(2)){
+  if ((aVToler2D(2) < (rst1->FirstParameter() - v)) ||
+      ((v - rst1->LastParameter()) > aVToler2D(2)))
+  {
     SituOnC1 = TopAbs_OUT;
   }
   else if (v > rst1->FirstParameter() &&
@@ -1720,8 +1714,9 @@ Standard_Boolean BRepBlend_RstRstLineBuilder::CheckInside(Blend_RstRstFunction&
 
   //face pcurve 2.
   v = sol(2);
-  if(v < rst2->FirstParameter() - tolerance(2)||
-     v > rst2->LastParameter() + tolerance(2)){
+  if ((aVToler2D(2) < (rst2->FirstParameter() - v)) ||
+      ((v - rst2->LastParameter()) > aVToler2D(2)))
+  {
     SituOnC2 = TopAbs_OUT;
   }
   else if (v > rst2->FirstParameter() &&
diff --git a/src/BRepBlend/BRepBlend_RstRstLineBuilder.hxx b/src/BRepBlend/BRepBlend_RstRstLineBuilder.hxx
index 138704d..46589c7 100644
--- a/src/BRepBlend/BRepBlend_RstRstLineBuilder.hxx
+++ b/src/BRepBlend/BRepBlend_RstRstLineBuilder.hxx
@@ -102,13 +102,6 @@ public:
 
 protected:
 
-
-
-
-
-private:
-
-  
   Standard_EXPORT void InternalPerform (Blend_RstRstFunction& Func, Blend_SurfCurvFuncInv& Finv1, Blend_CurvPointFuncInv& FinvP1, Blend_SurfCurvFuncInv& Finv2, Blend_CurvPointFuncInv& FinvP2, const Standard_Real Bound);
   
   Standard_EXPORT Standard_Boolean Recadre1 (Blend_RstRstFunction& Func, Blend_SurfCurvFuncInv& Finv, math_Vector& Solinv, Standard_Boolean& IsVtx, Handle(Adaptor3d_HVertex)& Vtx);
@@ -132,16 +125,20 @@ private:
   Standard_EXPORT Standard_Boolean CheckInside (Blend_RstRstFunction& Func, TopAbs_State& SituOnC1, TopAbs_State& SituOnC2, Blend_DecrochStatus& Decroch);
 
 
+
+
+private:
+
   Standard_Boolean done;
   Handle(BRepBlend_Line) line;
   math_Vector sol;
   Handle(Adaptor3d_HSurface) surf1;
-  Handle(Adaptor3d_TopolTool) domain1;
+  Handle(Adaptor3d_TopolTool) myDomain1;
   Handle(Adaptor3d_HSurface) surf2;
-  Handle(Adaptor3d_TopolTool) domain2;
+  Handle(Adaptor3d_TopolTool) myDomain2;
   Handle(Adaptor2d_HCurve2d) rst1;
   Handle(Adaptor2d_HCurve2d) rst2;
-  Standard_Real tolesp;
+  Standard_Real my3DTolEsp;
   Standard_Real tolgui;
   Standard_Real pasmax;
   Standard_Real fleche;
diff --git a/src/BRepBlend/BRepBlend_SurfRstLineBuilder.cxx b/src/BRepBlend/BRepBlend_SurfRstLineBuilder.cxx
index 40adf8d..81095fd 100644
--- a/src/BRepBlend/BRepBlend_SurfRstLineBuilder.cxx
+++ b/src/BRepBlend/BRepBlend_SurfRstLineBuilder.cxx
@@ -176,17 +176,16 @@ Standard_Integer BRepBlend_SurfRstLineBuilder::
   if(byinter) previousP.ParametersOnS(uprev,vprev);
   pt2d.SetCoord(theSol(1),theSol(2));
   lastpt2d.SetCoord(uprev,vprev);
-  domain1->Init();
+  myDomain1->Init();
 
-  while (domain1->More()) {
+  while (myDomain1->More()) {
     nbarc++; ok = 0;
     if(byinter) { 
-      ok = okinter = BRepBlend_BlendTool::Inters(pt2d,lastpt2d,
-						 surf1,
-						 domain1->Value(),prm,dist); 
+      ok = okinter = BRepBlend_BlendTool::Inters(pt2d,lastpt2d, surf1,
+						 myDomain1->Value(),prm,dist); 
     }
     if(!ok) ok = BRepBlend_BlendTool::Project(pt2d,surf1,
-					      domain1->Value(),prm,dist);
+                                              myDomain1->Value(), prm, dist);
 
     if (ok && (nbarc != PrevIndex) ) {
       if (dist<distmin || okinter) {
@@ -196,7 +195,7 @@ Standard_Integer BRepBlend_SurfRstLineBuilder::
 	if(okinter && (PrevIndex==0) ) break;
       }
     }
-    domain1->Next();
+    myDomain1->Next();
   }
   return IndexSol;
 }
@@ -212,8 +211,8 @@ BRepBlend_SurfRstLineBuilder::BRepBlend_SurfRstLineBuilder
  const Handle(Adaptor3d_HSurface)&  Surf2,
  const Handle(Adaptor2d_HCurve2d)&  Rst,
  const Handle(Adaptor3d_TopolTool)& Domain2):
- sol(1,3),surf1(Surf1), domain1(Domain1),
- surf2(Surf2), rst(Rst), domain2(Domain2)
+ sol(1, 3), surf1(Surf1), myDomain1(Domain1),
+ surf2(Surf2), rst(Rst), myDomain2(Domain2)
 {
 }
 
@@ -231,7 +230,7 @@ void BRepBlend_SurfRstLineBuilder::Perform(Blend_SurfRstFunction&  Func,
 					   const Standard_Real     MaxStep,
 					   const Standard_Real     TolGuide,
 					   const math_Vector&      ParDep,
-					   const Standard_Real     Tolesp,
+					   const Standard_Real     the3DTolEsp,
 					   const Standard_Real     Fleche,
 					   const Standard_Boolean  Appro) 
 {
@@ -239,7 +238,7 @@ void BRepBlend_SurfRstLineBuilder::Perform(Blend_SurfRstFunction&  Func,
   iscomplete = Standard_False;
   comptra = Standard_False;
   line = new BRepBlend_Line();
-  tolesp = Abs(Tolesp);
+  my3DTolEsp = Abs(the3DTolEsp);
   tolgui = Abs(TolGuide);
   fleche = Abs(Fleche);
   rebrou = Standard_False;
@@ -260,10 +259,10 @@ void BRepBlend_SurfRstLineBuilder::Perform(Blend_SurfRstFunction&  Func,
   if (Appro) {
     TopAbs_State siturst,situs;
     Standard_Boolean decroch;
-    math_Vector tolerance(1,3),infbound(1,3),supbound(1,3);
-    Func.GetTolerance(tolerance,tolesp);
+    math_Vector aVTol2D(1,3),infbound(1,3),supbound(1,3);
+    Func.GetTolerance(aVTol2D, my3DTolEsp);
     Func.GetBounds(infbound,supbound);
-    math_FunctionSetRoot rsnld(Func,tolerance,30);
+    math_FunctionSetRoot rsnld(Func, aVTol2D, 30);
     
     rsnld.Perform(Func,ParDep,infbound,supbound);
     
@@ -294,10 +293,10 @@ void BRepBlend_SurfRstLineBuilder::Perform(Blend_SurfRstFunction&  Func,
   previousP.ParametersOnS(U,V);
 //  W = previousP.ParameterOnC();
   
-  BRepBlend_Extremity ptf1(previousP.PointOnS(),
-			   U,V,previousP.Parameter(),tolesp);
-  BRepBlend_Extremity ptf2(previousP.PointOnC(),
-			   U,V,previousP.Parameter(),tolesp);
+  BRepBlend_Extremity ptf1(previousP.PointOnS(), U, V,
+                           previousP.Parameter(), my3DTolEsp);
+  BRepBlend_Extremity ptf2(previousP.PointOnC(), U, V, 
+                           previousP.Parameter(), my3DTolEsp);
   if (!previousP.IsTangencyPoint()) {
     ptf1.SetTangent(previousP.TangentOnS());
     ptf2.SetTangent(previousP.TangentOnC());
@@ -326,7 +325,7 @@ Standard_Boolean BRepBlend_SurfRstLineBuilder::PerformFirstSection
  const Standard_Real     Pdep,
  const Standard_Real     Pmax,
  const math_Vector&      ParDep,
- const Standard_Real     Tolesp,
+ const Standard_Real     the3DTolEsp,
  const Standard_Real     TolGuide,
  const Standard_Boolean  RecRst,
  const Standard_Boolean  RecP,
@@ -338,7 +337,7 @@ Standard_Boolean BRepBlend_SurfRstLineBuilder::PerformFirstSection
   iscomplete = Standard_False;
   comptra = Standard_False;
   line = new BRepBlend_Line();
-  tolesp = Abs(Tolesp);
+  my3DTolEsp = Abs(the3DTolEsp);
   tolgui = Abs(TolGuide);
   rebrou = Standard_False;
   
@@ -353,7 +352,7 @@ Standard_Boolean BRepBlend_SurfRstLineBuilder::PerformFirstSection
   Standard_Boolean recadp,recadrst,recads;
   Standard_Real wp,wrst,ws;
   Standard_Real U = 0.,V = 0.;
-  math_Vector infbound(1,3),supbound(1,3),tolerance(1,3);
+  math_Vector infbound(1,3),supbound(1,3),aVTol2D(1,3);
   math_Vector solinvp(1,3),solinvrst(1,4),solinvs(1,3);
   Handle(Adaptor3d_HVertex) Vtxp,Vtxrst,Vtxs,Vtxc;
   Standard_Boolean IsVtxp = 0,IsVtxrst = 0,IsVtxs = 0;
@@ -361,10 +360,10 @@ Standard_Boolean BRepBlend_SurfRstLineBuilder::PerformFirstSection
   wp = wrst = ws = Pmax;
   param = Pdep;
   Func.Set(param);
-  Func.GetTolerance(tolerance,tolesp);
+  Func.GetTolerance(aVTol2D, my3DTolEsp);
   Func.GetBounds(infbound,supbound);
 
-  math_FunctionSetRoot rsnld(Func,tolerance,30);
+  math_FunctionSetRoot rsnld(Func, aVTol2D, 30);
   rsnld.Perform(Func,ParDep,infbound,supbound);
   if (!rsnld.IsDone()) return Standard_False;
   rsnld.Root(sol);
@@ -526,7 +525,7 @@ void BRepBlend_SurfRstLineBuilder::InternalPerform(Blend_SurfRstFunction&  Func,
   Standard_Real U = 0.,V = 0.;
   Standard_Real trst = 0.;
   math_Vector infbound(1,3),supbound(1,3);
-  math_Vector parinit(1,3),tolerance(1,3);
+  math_Vector parinit(1,3),aVTol2D(1,3);
   math_Vector solinvp(1,3),solinvrst(1,4),solinvs(1,3);
   Handle(Adaptor3d_HVertex) Vtxp,Vtxrst,Vtxs,Vtxc;
   Standard_Boolean IsVtxp = 0,IsVtxrst = 0,IsVtxs = 0;
@@ -535,10 +534,10 @@ void BRepBlend_SurfRstLineBuilder::InternalPerform(Blend_SurfRstFunction&  Func,
 
   //IntSurf_Transition Tline,Tarc;
 
-  Func.GetTolerance(tolerance,tolesp);
+  Func.GetTolerance(aVTol2D, my3DTolEsp);
   Func.GetBounds(infbound,supbound);
 
-  math_FunctionSetRoot rsnld(Func,tolerance,30);
+  math_FunctionSetRoot rsnld(Func, aVTol2D, 30);
   parinit = sol;
 
   Arrive = Standard_False;
@@ -743,9 +742,8 @@ void BRepBlend_SurfRstLineBuilder::InternalPerform(Blend_SurfRstFunction&  Func,
 	
 	if (param == Bound) {
 	  Arrive = Standard_True;
-	  Exts.SetValue(previousP.PointOnS(),
-			sol(1),sol(2),
-			previousP.Parameter(),tolesp);
+	  Exts.SetValue(previousP.PointOnS(), sol(1),sol(2),
+                        previousP.Parameter(), my3DTolEsp);
 	  MakeExtremity(Extrst,Standard_False,rst,sol(3),IsVtxrst,Vtxrst);
 	  // Indicate end on Bound.
 	}
@@ -764,10 +762,9 @@ void BRepBlend_SurfRstLineBuilder::InternalPerform(Blend_SurfRstFunction&  Func,
 	if (Abs(stepw) < tolgui) {
 	  previousP.ParametersOnS(U,V);
 	  Exts.SetValue(previousP.PointOnS(),U,V,
-			previousP.Parameter(),tolesp);
-	  Extrst.SetValue(previousP.PointOnC(),
-			  previousP.ParameterOnC(),
-			  previousP.Parameter(),tolesp);
+                        previousP.Parameter(), my3DTolEsp);
+	  Extrst.SetValue(previousP.PointOnC(), previousP.ParameterOnC(),
+                          previousP.Parameter(), my3DTolEsp);
 	  Arrive = Standard_True;
 	  if (line->NbPoints()>=2) {
 	    // Indicate that one stops during the processing
@@ -803,7 +800,7 @@ void BRepBlend_SurfRstLineBuilder::InternalPerform(Blend_SurfRstFunction&  Func,
 	if (param == Bound) {
 	  Arrive = Standard_True;
 	  Exts.SetValue(previousP.PointOnS(),sol(1),sol(2),
-			previousP.Parameter(),tolesp);
+                        previousP.Parameter(), my3DTolEsp);
 	  MakeExtremity(Extrst,Standard_False,rst,sol(3),IsVtxrst,Vtxrst);
 	  // Indicate end on Bound.
 	}
@@ -849,7 +846,7 @@ void BRepBlend_SurfRstLineBuilder::InternalPerform(Blend_SurfRstFunction&  Func,
 	  line->Prepend(previousP);
 	}
 	Exts.SetValue(previousP.PointOnS(),sol(1),sol(2),
-		      previousP.Parameter(),tolesp);
+                      previousP.Parameter(), my3DTolEsp);
 	MakeExtremity(Extrst,Standard_False,rst,sol(3),IsVtxrst,Vtxrst);
 	Arrive = Standard_True;
       }
@@ -882,10 +879,10 @@ void BRepBlend_SurfRstLineBuilder::InternalPerform(Blend_SurfRstFunction&  Func,
 #endif
 	previousP.ParametersOnS(U,V);
 	Exts.SetValue(previousP.PointOnS(),U,V,
-		      previousP.Parameter(),tolesp);
+                      previousP.Parameter(), my3DTolEsp);
 	Extrst.SetValue(previousP.PointOnC(),
 			previousP.ParameterOnC(),
-			previousP.Parameter(),tolesp);
+                        previousP.Parameter(), my3DTolEsp);
 	Arrive = Standard_True;
       }
       break;
@@ -929,24 +926,24 @@ Standard_Boolean BRepBlend_SurfRstLineBuilder::Recadre(Blend_SurfCurvFuncInv&
     return Standard_False;
   }
 
-  domain1->Init();
+  myDomain1->Init();
   nbarc = 1;
   while (nbarc < IndexSol) {
     nbarc++;
-    domain1->Next();
+    myDomain1->Next();
   }
-  Arc = domain1->Value();
+  Arc = myDomain1->Value();
 
   FinvC.Set(Arc);
   
-  math_Vector toler(1,3),infb(1,3),supb(1,3);
-  FinvC.GetTolerance(toler,tolesp);
+  math_Vector aVTol2D(1,3),infb(1,3),supb(1,3);
+  FinvC.GetTolerance(aVTol2D, my3DTolEsp);
   FinvC.GetBounds(infb,supb);
   Solinv(1) = param;
   Solinv(2) = sol(3);
   Solinv(3) = pmin;
   
-  math_FunctionSetRoot rsnld(FinvC,toler,30);
+  math_FunctionSetRoot rsnld(FinvC,aVTol2D,30);
   rsnld.Perform(FinvC,Solinv,infb,supb);
 
   if (!rsnld.IsDone()) {
@@ -957,7 +954,7 @@ Standard_Boolean BRepBlend_SurfRstLineBuilder::Recadre(Blend_SurfCurvFuncInv&
   else {
       // It is necessary to check the value of the function
     rsnld.Root(Solinv);
-    recadre = FinvC.IsSolution(Solinv,tolesp);
+    recadre = FinvC.IsSolution(Solinv, my3DTolEsp);
   }
 
   // In case of fail, it is checked if another arc 
@@ -970,22 +967,22 @@ Standard_Boolean BRepBlend_SurfRstLineBuilder::Recadre(Blend_SurfCurvFuncInv&
       return Standard_False; // No other solution
     }
 
-    domain1->Init();
+    myDomain1->Init();
     nbarc = 1;
     while (nbarc < IndexSol) {
       nbarc++;
-      domain1->Next();
+      myDomain1->Next();
     }
 
-    Arc = domain1->Value();
+    Arc = myDomain1->Value();
     FinvC.Set(Arc);
   
-    FinvC.GetTolerance(toler,tolesp);
+    FinvC.GetTolerance(aVTol2D, my3DTolEsp);
     FinvC.GetBounds(infb,supb);
 
     Solinv(3) = pmin;
   
-    math_FunctionSetRoot aRsnld(FinvC,toler,30);
+    math_FunctionSetRoot aRsnld(FinvC,aVTol2D,30);
     aRsnld.Perform(FinvC,Solinv,infb,supb);
 
     if (!aRsnld.IsDone()) {
@@ -996,31 +993,31 @@ Standard_Boolean BRepBlend_SurfRstLineBuilder::Recadre(Blend_SurfCurvFuncInv&
     else {
       // It is necessary to check the value of the function
       aRsnld.Root(Solinv);
-      recadre = FinvC.IsSolution(Solinv,tolesp);
+      recadre = FinvC.IsSolution(Solinv, my3DTolEsp);
     }
   }  
 
   if (recadre) {
     Standard_Real w = Solinv(2);
-    if(w < rst->FirstParameter() - toler(2)||
-       w > rst->LastParameter() + toler(2)){
+    if((aVTol2D(2) < (rst->FirstParameter() - w)) ||
+       ((w - rst->LastParameter()) > aVTol2D(2))){
       return Standard_False;
     }
-    domain1->Initialize(Arc);
-    domain1->InitVertexIterator();
-    IsVtx = !domain1->MoreVertex();
+    myDomain1->Initialize(Arc);
+    myDomain1->InitVertexIterator();
+    IsVtx = !myDomain1->MoreVertex();
     while (!IsVtx) {
-      Vtx = domain1->Vertex();
+      Vtx = myDomain1->Vertex();
       if (Abs(BRepBlend_BlendTool::Parameter(Vtx,Arc)-Solinv(3)) <=
 	  BRepBlend_BlendTool::Tolerance(Vtx,Arc)) {
 	IsVtx = Standard_True;
       }
       else {
-	domain1->NextVertex();
-	IsVtx = !domain1->MoreVertex();
+        myDomain1->NextVertex();
+        IsVtx = !myDomain1->MoreVertex();
       }
     }
-    if (!domain1->MoreVertex()) {
+    if (!myDomain1->MoreVertex()) {
       IsVtx = Standard_False;
     }
     return Standard_True;
@@ -1039,15 +1036,15 @@ Standard_Boolean BRepBlend_SurfRstLineBuilder::Recadre(Blend_SurfRstFunction&
 						       Standard_Boolean&        IsVtx,
 						       Handle(Adaptor3d_HVertex)& Vtx) 
 {
-  math_Vector toler(1,4),infb(1,4),supb(1,4);
-  Finv.GetTolerance(toler,tolesp);
+  math_Vector aVTol2D(1,4),infb(1,4),supb(1,4);
+  Finv.GetTolerance(aVTol2D, my3DTolEsp);
   Finv.GetBounds(infb,supb);
   Solinv(1) = sol(3);
   Solinv(2) = param;
   Solinv(3) = sol(1);
   Solinv(4) = sol(2);
 
-  math_FunctionSetRoot rsnld(Finv,toler,30);
+  math_FunctionSetRoot rsnld(Finv,aVTol2D,30);
   rsnld.Perform(Finv,Solinv,infb,supb);
   if (!rsnld.IsDone()) {
 #ifdef OCCT_DEBUG
@@ -1057,38 +1054,38 @@ Standard_Boolean BRepBlend_SurfRstLineBuilder::Recadre(Blend_SurfRstFunction&
   }
   rsnld.Root(Solinv);
   
-  if(Finv.IsSolution(Solinv,tolesp)){
+  if (Finv.IsSolution(Solinv, my3DTolEsp)){
     gp_Pnt2d p2d(Solinv(3),Solinv(4));
-    TopAbs_State situ = domain1->Classify(p2d,Min(toler(3),toler(4)),0);
+    TopAbs_State situ = myDomain1->Classify(p2d, my3DTolEsp, Standard_False);
     if ((situ != TopAbs_IN) && (situ != TopAbs_ON)) {
       return Standard_False;
     }
-    domain2->Initialize(rst);
-    domain2->InitVertexIterator();
-    IsVtx = !domain2->MoreVertex();
+    myDomain2->Initialize(rst);
+    myDomain2->InitVertexIterator();
+    IsVtx = !myDomain2->MoreVertex();
     while (!IsVtx) {
-      Vtx = domain2->Vertex();
+      Vtx = myDomain2->Vertex();
       if (Abs(BRepBlend_BlendTool::Parameter(Vtx,rst)-Solinv(1)) <=
 	  BRepBlend_BlendTool::Tolerance(Vtx,rst)) {
 	IsVtx = Standard_True;
       }
       else {
-	domain2->NextVertex();
-	IsVtx = !domain2->MoreVertex();
+	myDomain2->NextVertex();
+	IsVtx = !myDomain2->MoreVertex();
       }
     }
-    if (!domain2->MoreVertex()) {
+    if (!myDomain2->MoreVertex()) {
       IsVtx = Standard_False;
     }
     // The section is recalculated by direct resolution, otherwise 
     // incoherences between the parameter and the ground caused by yawn are returned.
 
     math_Vector infbound(1,3),supbound(1,3);
-    math_Vector parinit(1,3),tolerance(1,3);
-    Func.GetTolerance(tolerance,tolesp);
+    math_Vector parinit(1,3),aVTol2D(1,3);
+    Func.GetTolerance(aVTol2D, my3DTolEsp);
     Func.GetBounds(infbound,supbound);
 
-    math_FunctionSetRoot rsnld2(Func,tolerance,30);
+    math_FunctionSetRoot rsnld2(Func,aVTol2D,30);
     parinit(1) = Solinv(3);
     parinit(2) = Solinv(4);
     parinit(3) = Solinv(1);
@@ -1124,14 +1121,14 @@ Standard_Boolean BRepBlend_SurfRstLineBuilder::Recadre(Blend_SurfPointFuncInv&
   gp_Pnt thepoint = surf2->Value(p2drst.X(),p2drst.Y());
 
   FinvP.Set(thepoint);
-  math_Vector toler(1,3),infb(1,3),supb(1,3);
-  FinvP.GetTolerance(toler,tolesp);
+  math_Vector aVTol2D(1,3),infb(1,3),supb(1,3);
+  FinvP.GetTolerance(aVTol2D, my3DTolEsp);
   FinvP.GetBounds(infb,supb);
   Solinv(1) = param;
   Solinv(2) = sol(1);
   Solinv(3) = sol(2);
 
-  math_FunctionSetRoot rsnld(FinvP,toler,30);
+  math_FunctionSetRoot rsnld(FinvP,aVTol2D,30);
   rsnld.Perform(FinvP,Solinv,infb,supb);
   if (!rsnld.IsDone()) {
 #ifdef OCCT_DEBUG
@@ -1141,27 +1138,27 @@ Standard_Boolean BRepBlend_SurfRstLineBuilder::Recadre(Blend_SurfPointFuncInv&
   }
   rsnld.Root(Solinv);
   
-  if(FinvP.IsSolution(Solinv,tolesp)){
+  if (FinvP.IsSolution(Solinv, my3DTolEsp)){
     gp_Pnt2d p2d(Solinv(2),Solinv(3));
-    TopAbs_State situ = domain1->Classify(p2d,Min(toler(2),toler(3)),0);
+    TopAbs_State situ = myDomain1->Classify(p2d, my3DTolEsp, Standard_False);
     if ((situ != TopAbs_IN) && (situ != TopAbs_ON)) {
       return Standard_False;
     }
-    domain2->Initialize(rst);
-    domain2->InitVertexIterator();
-    IsVtx = !domain2->MoreVertex();
+    myDomain2->Initialize(rst);
+    myDomain2->InitVertexIterator();
+    IsVtx = !myDomain2->MoreVertex();
     while (!IsVtx) {
-      Vtx = domain2->Vertex();
+      Vtx = myDomain2->Vertex();
       if (Abs(BRepBlend_BlendTool::Parameter(Vtx,rst)-wpoint) <=
 	  BRepBlend_BlendTool::Tolerance(Vtx,rst)) {
 	IsVtx = Standard_True;
       }
       else {
-	domain2->NextVertex();
-	IsVtx = !domain2->MoreVertex();
+        myDomain2->NextVertex();
+        IsVtx = !myDomain2->MoreVertex();
       }
     }
-    if (!domain2->MoreVertex()) {
+    if (!myDomain2->MoreVertex()) {
       IsVtx = Standard_False;
     }
     return Standard_True;
@@ -1234,20 +1231,18 @@ void BRepBlend_SurfRstLineBuilder::MakeExtremity(BRepBlend_Extremity&
   Standard_Real prm;
   Handle(Adaptor3d_TopolTool) Iter;
   if (OnFirst) {
-    Extrem.SetValue(previousP.PointOnS(),
-		    sol(1),sol(2),
-		    previousP.Parameter(),tolesp);
+    Extrem.SetValue(previousP.PointOnS(), sol(1),sol(2),
+                    previousP.Parameter(),my3DTolEsp);
     if (!previousP.IsTangencyPoint()) 
       Extrem.SetTangent(previousP.TangentOnS());
-    Iter = domain1;
+    Iter = myDomain1;
   }
   else {
-    Extrem.SetValue(previousP.PointOnC(),
-		    sol(3),
-		    previousP.Parameter(),tolesp);
+    Extrem.SetValue(previousP.PointOnC(), sol(3),
+                    previousP.Parameter(), my3DTolEsp);
     if (!previousP.IsTangencyPoint()) 
       Extrem.SetTangent(previousP.TangentOnC());    
-    Iter = domain2;
+    Iter = myDomain2;
   }
   
   Iter->Init();
@@ -1311,12 +1306,12 @@ Blend_Status BRepBlend_SurfRstLineBuilder::CheckDeflectionOnSurf(const Blend_Poi
 //  if(!curpointistangent) curNorme = Tgsurf.SquareMagnitude();
   if(!prevpointistangent) prevNorme = prevTg.SquareMagnitude();
 
-  if (Norme <= tolesp*tolesp){
+  if (Norme <= my3DTolEsp*my3DTolEsp){
     // it can be necessary to force same point
     return Blend_SamePoints;
   }
   if(!prevpointistangent){
-    if(prevNorme <= tolesp*tolesp) {
+    if (prevNorme <= my3DTolEsp*my3DTolEsp) {
       return Blend_SamePoints;
     }
     Cosi = sens*Corde*prevTg;
@@ -1387,12 +1382,12 @@ Blend_Status BRepBlend_SurfRstLineBuilder::CheckDeflectionOnRst(const Blend_Poin
 //  if(!curpointistangent) curNorme = Tgsurf.SquareMagnitude();
   if(!prevpointistangent) prevNorme = prevTg.SquareMagnitude();
 
-  if (Norme <= tolesp*tolesp){
+  if (Norme <= my3DTolEsp*my3DTolEsp){
     // it can be necessary to force same point
     return Blend_SamePoints;
   }
   if(!prevpointistangent){
-    if(prevNorme <= tolesp*tolesp) {
+    if (prevNorme <= my3DTolEsp*my3DTolEsp) {
       return Blend_SamePoints;
     }
     Cosi = sens*Corde*prevTg;
@@ -1454,7 +1449,7 @@ Blend_Status BRepBlend_SurfRstLineBuilder::TestArret(Blend_SurfRstFunction& Func
   IntSurf_TypeTrans tras = IntSurf_Undecided, trarst = IntSurf_Undecided;
   Blend_Point curpoint;
 
-  if (Func.IsSolution(sol,tolesp)) {
+  if (Func.IsSolution(sol, my3DTolEsp)) {
     Standard_Boolean curpointistangent = Func.IsTangencyPoint();
     pts = Func.PointOnS();
     ptrst = Func.PointOnRst();
@@ -1498,7 +1493,7 @@ Blend_Status BRepBlend_SurfRstLineBuilder::TestArret(Blend_SurfRstFunction& Func
       Func.Decroch(sol,nors,tgsecs);
       nors.Normalize();
       Standard_Real testra = tgsecs.Dot(nors.Crossed(tgs));
-      if (Abs(testra) > tolesp) {
+      if (Abs(testra) > my3DTolEsp) {
 	if (testra < 0.) {
 	  tras = IntSurf_In;
 	}
@@ -1508,7 +1503,7 @@ Blend_Status BRepBlend_SurfRstLineBuilder::TestArret(Blend_SurfRstFunction& Func
 	gp_Pnt2d p2drstref; gp_Vec2d tg2drstref;
 	rst->D1(sol(3),p2drstref,tg2drstref);
 	testra = tg2drst.Dot(tg2drstref);
-	TopAbs_Orientation Or = domain2->Orientation(rst);
+	TopAbs_Orientation Or = myDomain2->Orientation(rst);
 	if (Abs(testra) > 1.e-8) {
 	  if (testra < 0.) {
 	    trarst = ConvOrToTra(TopAbs::Reverse(Or));
@@ -1556,23 +1551,25 @@ Standard_Boolean BRepBlend_SurfRstLineBuilder::CheckInside(Blend_SurfRstFunction
 							   TopAbs_State&          SituOnS,
 							   Standard_Boolean&      Decroch)
 {
-  math_Vector tolerance(1,3);
-  Func.GetTolerance(tolerance,tolesp);
+  math_Vector aVTol2D(1,3);
+  Func.GetTolerance(aVTol2D, my3DTolEsp);
   //face pcurve.
   Standard_Real w = sol(3);
-  if(w < rst->FirstParameter() - tolerance(3)||
-     w > rst->LastParameter() + tolerance(3)){
+  if((aVTol2D(3) < (rst->FirstParameter() - w)) ||
+     ((w - rst->LastParameter()) > aVTol2D(3)))
+  {
     SituOnC = TopAbs_OUT;
   }
   else if (w > rst->FirstParameter() &&
-	   w < rst->LastParameter()){
+           w < rst->LastParameter())
+  {
     SituOnC = TopAbs_IN;
   }
   else SituOnC = TopAbs_ON;
 
   //face surface
   gp_Pnt2d p2d(sol(1),sol(2));
-  SituOnS = domain1->Classify(p2d,Min(tolerance(1),tolerance(2)),0);
+  SituOnS = myDomain1->Classify(p2d, my3DTolEsp, Standard_False);
 
   //lost contact
   gp_Vec tgs,nors;
diff --git a/src/BRepBlend/BRepBlend_SurfRstLineBuilder.hxx b/src/BRepBlend/BRepBlend_SurfRstLineBuilder.hxx
index 62c2330..d9aa145 100644
--- a/src/BRepBlend/BRepBlend_SurfRstLineBuilder.hxx
+++ b/src/BRepBlend/BRepBlend_SurfRstLineBuilder.hxx
@@ -133,11 +133,11 @@ private:
   Handle(BRepBlend_Line) line;
   math_Vector sol;
   Handle(Adaptor3d_HSurface) surf1;
-  Handle(Adaptor3d_TopolTool) domain1;
+  Handle(Adaptor3d_TopolTool) myDomain1;
   Handle(Adaptor3d_HSurface) surf2;
   Handle(Adaptor2d_HCurve2d) rst;
-  Handle(Adaptor3d_TopolTool) domain2;
-  Standard_Real tolesp;
+  Handle(Adaptor3d_TopolTool) myDomain2;
+  Standard_Real my3DTolEsp;
   Standard_Real tolgui;
   Standard_Real pasmax;
   Standard_Real fleche;
diff --git a/src/BRepBlend/BRepBlend_Walking.hxx b/src/BRepBlend/BRepBlend_Walking.hxx
index 974703c..5f837e7 100644
--- a/src/BRepBlend/BRepBlend_Walking.hxx
+++ b/src/BRepBlend/BRepBlend_Walking.hxx
@@ -101,13 +101,6 @@ public:
 
 protected:
 
-
-
-
-
-private:
-
-  
   Standard_EXPORT void InternalPerform (Blend_Function& F, Blend_FuncInv& FInv, const Standard_Real Bound);
   
   Standard_EXPORT Standard_Boolean CorrectExtremityOnOneRst (const Standard_Integer IndexOfRst, const Standard_Real theU, const Standard_Real theV, const Standard_Real theParam, const gp_Pnt& thePntOnRst, Standard_Real& NewU, Standard_Real& NewV, gp_Pnt& NewPoint, Standard_Real& NewParam) const;
@@ -127,21 +120,25 @@ private:
   Standard_EXPORT Blend_Status TestArret (Blend_Function& F, const Blend_Status State, const Standard_Boolean TestDeflection = Standard_True, const Standard_Boolean TestSolution = Standard_True, const Standard_Boolean TestLengthStep = Standard_False);
 
 
+
+
+private:
+
   Blend_Point previousP;
   Handle(BRepBlend_Line) line;
   math_Vector sol;
   Blend_SequenceOfPoint jalons;
   Handle(Adaptor3d_HSurface) surf1;
   Handle(Adaptor3d_HSurface) surf2;
-  Handle(Adaptor3d_TopolTool) domain1;
-  Handle(Adaptor3d_TopolTool) domain2;
-  Handle(Adaptor3d_TopolTool) recdomain1;
-  Handle(Adaptor3d_TopolTool) recdomain2;
+  Handle(Adaptor3d_TopolTool) myDomain1;
+  Handle(Adaptor3d_TopolTool) myDomain2;
+  Handle(Adaptor3d_TopolTool) myRecDomain1;
+  Handle(Adaptor3d_TopolTool) myRecDomain2;
   Handle(ChFiDS_HElSpine) hguide;
   Standard_Boolean ToCorrectOnRst1;
   Standard_Boolean ToCorrectOnRst2;
   Standard_Real CorrectedParam;
-  Standard_Real tolesp;
+  Standard_Real my3DTolEsp;
   Standard_Real tolgui;
   Standard_Real pasmax;
   Standard_Real fleche;
diff --git a/src/BRepBndLib/BRepBndLib.cxx b/src/BRepBndLib/BRepBndLib.cxx
index b739683..5d3a8e9 100644
--- a/src/BRepBndLib/BRepBndLib.cxx
+++ b/src/BRepBndLib/BRepBndLib.cxx
@@ -693,7 +693,8 @@ void AdjustFaceBox(const BRepAdaptor_Surface& BS,
                    const Standard_Real umin, const Standard_Real umax, 
                    const Standard_Real vmin, const Standard_Real vmax,
                    Bnd_Box& FaceBox,
-                   const Bnd_Box& EdgeBox, const Standard_Real Tol)
+                   const Bnd_Box& EdgeBox,
+                   const Standard_Real Tol)
 {
   Standard_Real fxmin, fymin, fzmin, fxmax, fymax, fzmax;
   Standard_Real exmin, eymin, ezmin, exmax, eymax, ezmax;
@@ -701,9 +702,9 @@ void AdjustFaceBox(const BRepAdaptor_Surface& BS,
   FaceBox.Get(fxmin, fymin, fzmin, fxmax, fymax, fzmax);
   EdgeBox.Get(exmin, eymin, ezmin, exmax, eymax, ezmax);
   //
-  Standard_Real TolU = Max(BS.UResolution(Tol), Precision::PConfusion());
-  Standard_Real TolV = Max(BS.VResolution(Tol), Precision::PConfusion());
-  BRepTopAdaptor_FClass2d FClass(BS.Face(), Max(TolU, TolV));
+  BRepTopAdaptor_FClass2d FClass(BS.Face(), Tol);
+  const Standard_Real TolU = Max(BS.UResolution(Tol), Precision::PConfusion());
+  const Standard_Real TolV = Max(BS.VResolution(Tol), Precision::PConfusion());
   //
   Standard_Boolean isModified = Standard_False;
   if(exmin > fxmin)
diff --git a/src/BRepCheck/BRepCheck_Face.cxx b/src/BRepCheck/BRepCheck_Face.cxx
index fd500c5..3b53dc1 100644
--- a/src/BRepCheck/BRepCheck_Face.cxx
+++ b/src/BRepCheck/BRepCheck_Face.cxx
@@ -323,9 +323,17 @@ BRepCheck_Status BRepCheck_Face::ClassifyWires(const Standard_Boolean Update)
     newFace.Orientation(TopAbs_FORWARD);
     B.Add(newFace,wir1);
 
-    BRepTopAdaptor_FClass2d FClass2d(newFace,Precision::PConfusion());
+    BRepTopAdaptor_FClass2d FClass2d(newFace,Precision::Confusion());
     Standard_Boolean WireBienOriente = Standard_False;
-    if(FClass2d.PerformInfinitePoint() != TopAbs_OUT) { 
+    TopAbs_State aState = FClass2d.PerformInfinitePoint();
+    if (aState == TopAbs_UNKNOWN) {
+      myOrires = BRepCheck_UnorientableShape;
+      if (Update) {
+        BRepCheck::Add(myMap(myShape), myOrires);
+      }
+      return myOrires;
+    }
+    if (aState == TopAbs_IN) {
       WireBienOriente=Standard_True;
       // the given wire defines a hole
       myMapImb.UnBind(wir1);
diff --git a/src/BRepClass/BRepClass_Edge.cxx b/src/BRepClass/BRepClass_Edge.cxx
deleted file mode 100644
index c4cbc44..0000000
--- a/src/BRepClass/BRepClass_Edge.cxx
+++ /dev/null
@@ -1,41 +0,0 @@
-// Created on: 1992-11-19
-// Created by: Remi LEQUETTE
-// Copyright (c) 1992-1999 Matra Datavision
-// Copyright (c) 1999-2014 OPEN CASCADE SAS
-//
-// This file is part of Open CASCADE Technology software library.
-//
-// This library is free software; you can redistribute it and/or modify it under
-// the terms of the GNU Lesser General Public License version 2.1 as published
-// by the Free Software Foundation, with special exception defined in the file
-// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
-// distribution for complete text of the license and disclaimer of any warranty.
-//
-// Alternatively, this file may be used under the terms of Open CASCADE
-// commercial license or contractual agreement.
-
-
-#include <BRepClass_Edge.hxx>
-#include <TopoDS_Edge.hxx>
-#include <TopoDS_Face.hxx>
-
-//=======================================================================
-//function : BRepClass_Edge
-//purpose  : 
-//=======================================================================
-BRepClass_Edge::BRepClass_Edge()
-{
-}
-
-//=======================================================================
-//function : BRepClass_Edge
-//purpose  : 
-//=======================================================================
-
-BRepClass_Edge::BRepClass_Edge(const TopoDS_Edge& E,
-			       const TopoDS_Face& F) :
-       myEdge(E),
-       myFace(F)
-{
-}
-
diff --git a/src/BRepClass/BRepClass_Edge.hxx b/src/BRepClass/BRepClass_Edge.hxx
deleted file mode 100644
index 9c07502..0000000
--- a/src/BRepClass/BRepClass_Edge.hxx
+++ /dev/null
@@ -1,76 +0,0 @@
-// Created on: 1992-11-19
-// Created by: Remi LEQUETTE
-// Copyright (c) 1992-1999 Matra Datavision
-// Copyright (c) 1999-2014 OPEN CASCADE SAS
-//
-// This file is part of Open CASCADE Technology software library.
-//
-// This library is free software; you can redistribute it and/or modify it under
-// the terms of the GNU Lesser General Public License version 2.1 as published
-// by the Free Software Foundation, with special exception defined in the file
-// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
-// distribution for complete text of the license and disclaimer of any warranty.
-//
-// Alternatively, this file may be used under the terms of Open CASCADE
-// commercial license or contractual agreement.
-
-#ifndef _BRepClass_Edge_HeaderFile
-#define _BRepClass_Edge_HeaderFile
-
-#include <Standard.hxx>
-#include <Standard_DefineAlloc.hxx>
-#include <Standard_Handle.hxx>
-
-#include <TopoDS_Edge.hxx>
-#include <TopoDS_Face.hxx>
-class TopoDS_Edge;
-class TopoDS_Face;
-
-
-//! This class  is used to send  the  description of an
-//! Edge to the classifier. It  contains  an Edge and a
-//! Face. So the PCurve of the Edge can be found.
-class BRepClass_Edge 
-{
-public:
-
-  DEFINE_STANDARD_ALLOC
-
-  
-  Standard_EXPORT BRepClass_Edge();
-  
-  Standard_EXPORT BRepClass_Edge(const TopoDS_Edge& E, const TopoDS_Face& F);
-  
-    TopoDS_Edge& Edge();
-const TopoDS_Edge& Edge() const;
-  
-    TopoDS_Face& Face();
-const TopoDS_Face& Face() const;
-
-
-
-
-protected:
-
-
-
-
-
-private:
-
-
-
-  TopoDS_Edge myEdge;
-  TopoDS_Face myFace;
-
-
-};
-
-
-#include <BRepClass_Edge.lxx>
-
-
-
-
-
-#endif // _BRepClass_Edge_HeaderFile
diff --git a/src/BRepClass/BRepClass_Edge.lxx b/src/BRepClass/BRepClass_Edge.lxx
deleted file mode 100644
index 07b362a..0000000
--- a/src/BRepClass/BRepClass_Edge.lxx
+++ /dev/null
@@ -1,56 +0,0 @@
-// Created on: 1992-11-19
-// Created by: Remi LEQUETTE
-// Copyright (c) 1992-1999 Matra Datavision
-// Copyright (c) 1999-2014 OPEN CASCADE SAS
-//
-// This file is part of Open CASCADE Technology software library.
-//
-// This library is free software; you can redistribute it and/or modify it under
-// the terms of the GNU Lesser General Public License version 2.1 as published
-// by the Free Software Foundation, with special exception defined in the file
-// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
-// distribution for complete text of the license and disclaimer of any warranty.
-//
-// Alternatively, this file may be used under the terms of Open CASCADE
-// commercial license or contractual agreement.
-
-//=======================================================================
-//function : Edge
-//purpose  : 
-//=======================================================================
-
-inline TopoDS_Edge& BRepClass_Edge::Edge() 
-{
-  return  myEdge;
-}
-
-//=======================================================================
-//function : Edge
-//purpose  : 
-//=======================================================================
-
-inline const TopoDS_Edge& BRepClass_Edge::Edge() const
-{
-  return  myEdge;
-}
-
-//=======================================================================
-//function : Face
-//purpose  : 
-//=======================================================================
-
-inline TopoDS_Face& BRepClass_Edge::Face() 
-{
-  return myFace;
-}
-
-//=======================================================================
-//function : Face
-//purpose  : 
-//=======================================================================
-
-inline const TopoDS_Face& BRepClass_Edge::Face() const
-{
-  return myFace;
-}
-
diff --git a/src/BRepClass/BRepClass_FClass2dOfFClassifier.hxx b/src/BRepClass/BRepClass_FClass2dOfFClassifier.hxx
index 492066a..84b8a33 100644
--- a/src/BRepClass/BRepClass_FClass2dOfFClassifier.hxx
+++ b/src/BRepClass/BRepClass_FClass2dOfFClassifier.hxx
@@ -19,22 +19,13 @@
 
 #include <Standard.hxx>
 #include <Standard_DefineAlloc.hxx>
-#include <Standard_Handle.hxx>
 
-#include <Standard_Boolean.hxx>
-#include <gp_Lin2d.hxx>
-#include <Standard_Real.hxx>
-#include <TopTrans_CurveTransition.hxx>
 #include <BRepClass_Intersector.hxx>
-#include <Standard_Integer.hxx>
 #include <TopAbs_State.hxx>
-#include <TopAbs_Orientation.hxx>
-class Standard_DomainError;
-class BRepClass_Edge;
-class BRepClass_Intersector;
-class gp_Lin2d;
-
+#include <TopTrans_CurveTransition.hxx>
 
+class gp_Lin2d;
+class TopClass_GeomEdge;
 
 class BRepClass_FClass2dOfFClassifier 
 {
@@ -49,13 +40,15 @@ public:
   //! Starts  a  classification process.   The  point to
   //! classify is the origin of  the  line <L>.  <P>  is
   //! the original length of the segment on <L>  used to
-  //! compute  intersections.   <Tol> is the   tolerance
-  //! attached to the line segment in intersections.
-  Standard_EXPORT void Reset (const gp_Lin2d& L, const Standard_Real P, const Standard_Real Tol);
+  //! compute  intersections.
+  Standard_EXPORT void Reset (const gp_Lin2d& L, const Standard_Real P);
   
   //! Updates  the classification process with  the edge
-  //! <E> from the boundary.
-  Standard_EXPORT void Compare (const BRepClass_Edge& E, const TopAbs_Orientation Or);
+  //! <theE> from the boundary.
+  //! theTol2D is 2D-tolerance using in intersector of theE with
+  //! the linear ray myLin
+  Standard_EXPORT void Compare(const TopClass_GeomEdge& theE,
+                               const Standard_Real theTol2D);
   
   //! Returns the current value of the parameter.
     Standard_Real Parameter() const;
@@ -77,36 +70,22 @@ public:
   //! otherwise.
     Standard_Boolean IsHeadOrEnd() const;
 
-
-
-
 protected:
 
-
-
-
-
 private:
 
-
-
-  Standard_Boolean myIsSet;
   Standard_Boolean myFirstCompare;
   Standard_Boolean myFirstTrans;
   gp_Lin2d myLin;
   Standard_Real myParam;
-  Standard_Real myTolerance;
+
   TopTrans_CurveTransition myTrans;
   BRepClass_Intersector myIntersector;
   Standard_Integer myClosest;
   TopAbs_State myState;
   Standard_Boolean myIsHeadOrEnd;
-
-
 };
 
-#define TheEdge BRepClass_Edge
-#define TheEdge_hxx <BRepClass_Edge.hxx>
 #define TheIntersector BRepClass_Intersector
 #define TheIntersector_hxx <BRepClass_Intersector.hxx>
 #define TopClass_Classifier2d BRepClass_FClass2dOfFClassifier
@@ -114,14 +93,9 @@ private:
 
 #include <TopClass_Classifier2d.lxx>
 
-#undef TheEdge
-#undef TheEdge_hxx
 #undef TheIntersector
 #undef TheIntersector_hxx
 #undef TopClass_Classifier2d
 #undef TopClass_Classifier2d_hxx
 
-
-
-
 #endif // _BRepClass_FClass2dOfFClassifier_HeaderFile
diff --git a/src/BRepClass/BRepClass_FClass2dOfFClassifier_0.cxx b/src/BRepClass/BRepClass_FClass2dOfFClassifier_0.cxx
index d31e426..8420ba4 100644
--- a/src/BRepClass/BRepClass_FClass2dOfFClassifier_0.cxx
+++ b/src/BRepClass/BRepClass_FClass2dOfFClassifier_0.cxx
@@ -17,13 +17,10 @@
 #include <BRepClass_FClass2dOfFClassifier.hxx>
 
 #include <Standard_DomainError.hxx>
-#include <BRepClass_Edge.hxx>
+#include <TopClass_GeomEdge.hxx>
 #include <BRepClass_Intersector.hxx>
 #include <gp_Lin2d.hxx>
- 
 
-#define TheEdge BRepClass_Edge
-#define TheEdge_hxx <BRepClass_Edge.hxx>
 #define TheIntersector BRepClass_Intersector
 #define TheIntersector_hxx <BRepClass_Intersector.hxx>
 #define TopClass_Classifier2d BRepClass_FClass2dOfFClassifier
diff --git a/src/BRepClass/BRepClass_FClassifier.hxx b/src/BRepClass/BRepClass_FClassifier.hxx
index 359d8f9..384fc59 100644
--- a/src/BRepClass/BRepClass_FClassifier.hxx
+++ b/src/BRepClass/BRepClass_FClassifier.hxx
@@ -19,113 +19,64 @@
 
 #include <Standard.hxx>
 #include <Standard_DefineAlloc.hxx>
-#include <Standard_Handle.hxx>
 
-#include <BRepClass_FClass2dOfFClassifier.hxx>
-#include <BRepClass_Edge.hxx>
-#include <Standard_Real.hxx>
 #include <IntRes2d_Position.hxx>
-#include <Standard_Boolean.hxx>
-#include <TopAbs_State.hxx>
-class Standard_DomainError;
-class BRepClass_FaceExplorer;
-class BRepClass_Edge;
-class BRepClass_Intersector;
-class BRepClass_FClass2dOfFClassifier;
-class gp_Pnt2d;
-
+#include <TopClass_GeomEdge.hxx>
 
+class BRepClass_FaceExplorer;
 
-class BRepClass_FClassifier 
+class BRepClass_FClassifier
 {
 public:
 
   DEFINE_STANDARD_ALLOC
-
-  
+    
   //! Empty constructor, undefined algorithm.
   Standard_EXPORT BRepClass_FClassifier();
-  
-  //! Creates an algorithm to classify the Point  P with
-  //! Tolerance <T> on the face described by <F>.
-  Standard_EXPORT BRepClass_FClassifier(BRepClass_FaceExplorer& F, const gp_Pnt2d& P, const Standard_Real Tol);
-  
-  //! Classify  the Point  P  with  Tolerance <T> on the
-  //! face described by <F>.
-  Standard_EXPORT void Perform (BRepClass_FaceExplorer& F, const gp_Pnt2d& P, const Standard_Real Tol);
-  
+
+  //! Classifies the point <theP> 
+  //! relatively to the face from <theFE>.
+  //! theTol2D is 2D-tolerance used in intersector of the edge myEdge
+  //! with a linear ray going from the point theP
+  Standard_EXPORT void Perform(BRepClass_FaceExplorer& theFE,
+                               const gp_Pnt2d& theP,
+                               const Standard_Real theTol2D);
+
   //! Returns the result of the classification.
   Standard_EXPORT TopAbs_State State() const;
-  
-  //! Returns  True when  the   state was computed by  a
-  //! rejection. The state is OUT.
-    Standard_Boolean Rejected() const;
-  
-  //! Returns True if  the face  contains  no wire.  The
-  //! state is IN.
-    Standard_Boolean NoWires() const;
-  
+
   //! Returns   the    Edge  used   to    determine  the
   //! classification. When the State is ON  this  is the
   //! Edge containing the point.
-  Standard_EXPORT const BRepClass_Edge& Edge() const;
-  
+  //! This method is used only for compatibility with TopOpeBRep
+  //! packages. It should be deleted after this package will be eliminated.
+  const TopClass_GeomEdge& Edge() const
+  {
+    return myEdge;
+  }
+
   //! Returns the parameter on Edge() used to determine  the
   //! classification.
-  Standard_EXPORT Standard_Real EdgeParameter() const;
+  //! This method is used only for compatibility with TopOpeBRep
+  //! packages. It should be deleted after this package will be eliminated.
+  Standard_EXPORT Standard_Real EdgeParameter() const
+  {
+    return myEdgeParameter;
+  }
   
-  //! Returns the  position of  the   point on the  edge
-  //! returned by Edge.
-    IntRes2d_Position Position() const;
-
-
-
-
 protected:
+  //! ATTENTION!!!
+  //! Fields myEdge and myEdgeParameter
+  //! should be eliminated after removing TopOpeBRep*
+  //! packages.
 
-
-
-  BRepClass_FClass2dOfFClassifier myClassifier;
-  BRepClass_Edge myEdge;
+  TopClass_GeomEdge myEdge;
   Standard_Real myEdgeParameter;
-  IntRes2d_Position myPosition;
-  Standard_Boolean rejected;
-  Standard_Boolean nowires;
-
+  TopAbs_State myState;
 
 private:
 
-
-
-
-
 };
 
-#define TheFaceExplorer BRepClass_FaceExplorer
-#define TheFaceExplorer_hxx <BRepClass_FaceExplorer.hxx>
-#define TheEdge BRepClass_Edge
-#define TheEdge_hxx <BRepClass_Edge.hxx>
-#define TheIntersection2d BRepClass_Intersector
-#define TheIntersection2d_hxx <BRepClass_Intersector.hxx>
-#define TopClass_FClass2d BRepClass_FClass2dOfFClassifier
-#define TopClass_FClass2d_hxx <BRepClass_FClass2dOfFClassifier.hxx>
-#define TopClass_FaceClassifier BRepClass_FClassifier
-#define TopClass_FaceClassifier_hxx <BRepClass_FClassifier.hxx>
-
-#include <TopClass_FaceClassifier.lxx>
-
-#undef TheFaceExplorer
-#undef TheFaceExplorer_hxx
-#undef TheEdge
-#undef TheEdge_hxx
-#undef TheIntersection2d
-#undef TheIntersection2d_hxx
-#undef TopClass_FClass2d
-#undef TopClass_FClass2d_hxx
-#undef TopClass_FaceClassifier
-#undef TopClass_FaceClassifier_hxx
-
-
-
 
 #endif // _BRepClass_FClassifier_HeaderFile
diff --git a/src/BRepClass/BRepClass_FClassifier_0.cxx b/src/BRepClass/BRepClass_FClassifier_0.cxx
index fed7a7b..6e39498 100644
--- a/src/BRepClass/BRepClass_FClassifier_0.cxx
+++ b/src/BRepClass/BRepClass_FClassifier_0.cxx
@@ -18,7 +18,7 @@
 
 #include <Standard_DomainError.hxx>
 #include <BRepClass_FaceExplorer.hxx>
-#include <BRepClass_Edge.hxx>
+#include <TopClass_GeomEdge.hxx>
 #include <BRepClass_Intersector.hxx>
 #include <BRepClass_FClass2dOfFClassifier.hxx>
 #include <gp_Pnt2d.hxx>
@@ -26,8 +26,12 @@
 
 #define TheFaceExplorer BRepClass_FaceExplorer
 #define TheFaceExplorer_hxx <BRepClass_FaceExplorer.hxx>
-#define TheEdge BRepClass_Edge
-#define TheEdge_hxx <BRepClass_Edge.hxx>
+
+//! Are used only for compatibility with TopOpeBRep
+//! packages. It should be deleted after this package will be eliminated.
+#define TheTopoEdge TopoDS_Edge
+#define TheTopoEdge_hxx <TopoDS_Edge.hxx>
+
 #define TheIntersection2d BRepClass_Intersector
 #define TheIntersection2d_hxx <BRepClass_Intersector.hxx>
 #define TopClass_FClass2d BRepClass_FClass2dOfFClassifier
diff --git a/src/BRepClass/BRepClass_FaceClassifier.cxx b/src/BRepClass/BRepClass_FaceClassifier.cxx
index 8d1ba8c..f95a945 100644
--- a/src/BRepClass/BRepClass_FaceClassifier.cxx
+++ b/src/BRepClass/BRepClass_FaceClassifier.cxx
@@ -13,81 +13,290 @@
 // commercial license or contractual agreement.
 
 
+#include <BRep_Builder.hxx>
 #include <BRepAdaptor_HSurface.hxx>
 #include <BRepAdaptor_Surface.hxx>
 #include <BRepClass_FaceClassifier.hxx>
 #include <BRepClass_FaceExplorer.hxx>
+#include <BRepExtrema_DistShapeShape.hxx>
 #include <BRepTools.hxx>
+#include <BRepBndLib.hxx>
 #include <Extrema_ExtPS.hxx>
 #include <gp_Pnt.hxx>
 #include <gp_Pnt2d.hxx>
 #include <TopAbs_State.hxx>
+#include <TopExp.hxx>
+#include <TopoDS.hxx>
 #include <TopoDS_Face.hxx>
 
-//=======================================================================
-//function : BRepClass_FaceClassifier
-//purpose  : 
-//=======================================================================
-BRepClass_FaceClassifier::BRepClass_FaceClassifier()
-{
-}
+#if 0
+Standard_Boolean Check2D(const TopoDS_Edge &theTopE,
+                         const TopoDS_Face &theTopF,
+                         const Standard_Real theCurvParam,
+                         const gp_Pnt2d& thePRef,
+                         const Standard_Real theTol3D,
+                         const Standard_Boolean theIsOnClosedSurf);
+
+Standard_Boolean Check2D(const TopoDS_Vertex &theTopV,
+                         const TopoDS_Face &theTopF,
+                         const gp_Pnt2d& thePRef,
+                         const Standard_Real theTol3D);
+#else
+Standard_Boolean Check2D(const TopClass_GeomEdge& theGE,
+                         const Standard_Real theCurvParam,
+                         const gp_Pnt2d& thePRef,
+                         const Standard_Real theTol3D,
+                         gp_Pnt2d& thePOnC);
 
+#endif
 //=======================================================================
 //function : BRepClass_FaceClassifier
 //purpose  : 
 //=======================================================================
-BRepClass_FaceClassifier::BRepClass_FaceClassifier(BRepClass_FaceExplorer& F, 
-						   const gp_Pnt2d& P, 
-						   const Standard_Real Tol) 
-:
-  BRepClass_FClassifier(F,P,Tol)
+BRepClass_FaceClassifier::BRepClass_FaceClassifier():myFEx(TopoDS_Face())
 {
 }
+
 //=======================================================================
 //function : BRepClass_FaceClassifier
 //purpose  : 
 //=======================================================================
-BRepClass_FaceClassifier::BRepClass_FaceClassifier(const TopoDS_Face& F, 
-						   const gp_Pnt& P, 
-						   const Standard_Real Tol)
+BRepClass_FaceClassifier::BRepClass_FaceClassifier(const TopoDS_Face& theF, 
+                                                   const gp_Pnt& theP, 
+                                                   const Standard_Real theTol3D)
+: myFEx(theF)
 {
-  Perform(F,P,Tol);
+  Perform(theF, theP, theTol3D);
 }
 //=======================================================================
 //function : BRepClass_FaceClassifier
 //purpose  : 
 //=======================================================================
-BRepClass_FaceClassifier::BRepClass_FaceClassifier(const TopoDS_Face& F, 
-						   const gp_Pnt2d& P, 
-						   const Standard_Real Tol)
+BRepClass_FaceClassifier::
+            BRepClass_FaceClassifier(const TopoDS_Face& theF, 
+                                     const gp_Pnt2d& theP,
+                                     const Standard_Real theTol3D) : myFEx(theF)
 {
-  Perform(F,P,Tol);
+  Perform(theF, theP, theTol3D);
 }
 
 //=======================================================================
 //function : Perform
 //purpose  : 
 //=======================================================================
-void  BRepClass_FaceClassifier::Perform(const TopoDS_Face& F, 
-					const gp_Pnt2d& P, 
-					const Standard_Real Tol)
+void  BRepClass_FaceClassifier::Perform(const TopoDS_Face& theF, 
+                                        const gp_Pnt2d& theP, 
+                                        const Standard_Real theTol3D)
 {
-  BRepClass_FaceExplorer Fex(F);
-  BRepClass_FClassifier::Perform(Fex,P,Tol);
-}
+  // First, let's check of ON-status
+  
+#if 0
+  // Indeed, this code is more optimal than existing.
+  // However, it cannot be implemented until the bug #29288
+  // will be fixed.
+
+  const Standard_Real aSqTol = theTol3D*theTol3D;
+  const BRepAdaptor_Surface anAS(theF, Standard_False);
+  const gp_Pnt aPt(anAS.Value(theP.X(), theP.Y()));
+  TopoDS_Vertex aVert;
+  BRep_Builder aBB;
+  aBB.MakeVertex(aVert, aPt, Precision::Confusion());
+  TopoDS_Iterator aWirExp(theF);
+  for(; aWirExp.More(); aWirExp.Next())
+  {
+    // aWir is a wire
+    const TopoDS_Shape& aWir = aWirExp.Value();
+    BRepExtrema_DistShapeShape anExtr(aWir, aVert);
+    if(!anExtr.IsDone() || (anExtr.NbSolution() < 1))
+    {
+      continue;
+    }
+
+    if(anExtr.Value() > theTol3D)
+    {
+      continue;
+    }
+
+    // It is necessary for periodic and quasi-periodic (e.g. sphere)
+    // surfaces (tests bug28211_18, bug28211_32, bug28211_33 and
+    // bug28211_35 in "tests/lowalgos/classifier/").
+    // E.g. if 2D-distance between theP and the p-curve of some edge
+    // is equal to T (the surface period) then 3D-point
+    // corresponding to theP can be exactly in the edge.
+    // So, 3D-distance is less than theTol3D however,
+    // returning ON-status is wrong in this case.
+    // Therefore, check in 2D-space is executed.
+    
+    // ATTENTION!!!
+    // This check will be wrong if theTol3D covers the 2D-distance
+    // of the surface. I.e. if two 3D-points of any cylinder (for example)
+    // having 2D-coordinates (0, 0) and (PI, 0) can
+    // be considered as same with precision theTol3D.
+    // But for periodic surfaces, Check2D(...) method
+    // can return FALSE even if theTol3D is big
+    // (because this check is based on period value
+    // instead of tolerance).
+
+    for(Standard_Integer i = 1; i <= anExtr.NbSolution(); i++)
+    {
+      if(anExtr.PointOnShape1(i).SquareDistance(aPt) > aSqTol)
+        continue;
+
+      switch(anExtr.SupportTypeShape1(i))
+      {
+        case BRepExtrema_IsVertex:
+        {
+          const TopoDS_Shape aSh = anExtr.SupportOnShape1(i);
+          if(Check2D(TopoDS::Vertex(aSh), theF, theP, theTol3D))
+          {
+            myState = TopAbs_ON;
+            TopTools_IndexedDataMapOfShapeListOfShape aM;
+            TopExp::MapShapesAndAncestors(theF, TopAbs_VERTEX, TopAbs_EDGE, aM);
+            const TopoDS_Shape &anE = aM.FindFromKey(aSh).First();
+            myEdgeParameter = BRep_Tool::Parameter(TopoDS::Vertex(aSh), TopoDS::Edge(anE));
+            myEdge = TopClass_GeomEdge(TopoDS::Edge(anE), theF);
+            return;
+          }
+        }
+        break;
+
+        case BRepExtrema_IsOnEdge:
+        {
+          const TopoDS_Shape aSh = anExtr.SupportOnShape1(i);
+          const TopoDS_Edge &anE = TopoDS::Edge(aSh);
+
+          //Indeed, seam-edge is included to the wire aWir twice.
+          //However, BRepExtrema_DistShapeShape will return only one
+          //representation of the nearest edge (at that this representation
+          //is chosen randomly). Maybe the edge will be chosen whose p-curve
+          //is farer from the classified point. Therefore, we must
+          //check all CurveRepresentation of this edge. For that,
+          //the flag isOnClosedSurface is used.
+          Standard_Boolean isOnClosedSurface = BRep_Tool::IsClosed(anE, theF);
+
+          if(isOnClosedSurface)
+          {
+            // See face_with_rejected_seam.brep file attached to
+            // the issue #28211 (classified point has
+            // (-1.0000000000000004 0.48095952536907932) coordinates).
+            // This face contains the edge with two p-curves (on this face)
+            // but this edge is included in the face once (i.e. indeed it is
+            // not seam). It seems that the excess p-curve was not deleted
+            // after splitting of the face but it must not be taken into
+            // account when classifying.
+            // So, we need extend check here whether this edge is really met
+            // in the wire twice.
 
+            // Take edges
+            TopoDS_Iterator anItr(aWir);
+            for(; anItr.More(); anItr.Next())
+            {
+              const TopoDS_Edge &WE = TopoDS::Edge(anItr.Value());
+              if(anE.IsSame(WE))
+              {
+                isOnClosedSurface = !isOnClosedSurface;
+              }
+            }
+          }
 
+          Standard_Real aPar = 0.0;
+          anExtr.ParOnEdgeS1(i, aPar);
+          if(Check2D(anE, theF, aPar, theP, theTol3D, isOnClosedSurface))
+          {
+            myState = TopAbs_ON;
+            myEdgeParameter = aPar;
+            myEdge = TopClass_GeomEdge(TopoDS::Edge(aSh), theF);
+            return;
+          }
+        }
+        break;
 
+        default:
+          break;
+      }
+    }
+  }
+#else
+  const Handle(Geom_Surface) aS = BRep_Tool::Surface(theF);
+  gp_Pnt aP3d = aS->Value(theP.X(), theP.Y());
+  TopoDS_Iterator aWirExp(theF);
+  for(; aWirExp.More(); aWirExp.Next())
+  {
+    // aWir is a wire
+    const TopoDS_Shape& aWir = aWirExp.Value();
+    
+    TopoDS_Iterator anEExp(aWir);
+    for(; anEExp.More(); anEExp.Next())
+    {
+      // anE is an edge
+      const TopoDS_Edge& anE = TopoDS::Edge(anEExp.Value());
+
+      Bnd_Box aBox;
+      BRepBndLib::Add(anE, aBox);
+      aBox.Enlarge(theTol3D);
+      if (aBox.IsOut(aP3d))
+        continue;
+
+      Standard_Real aFPar, aLPar;
+      const Handle(Geom2d_Curve) aC2d = BRep_Tool::CurveOnSurface(anE, theF, aFPar, aLPar);
+      const TopClass_GeomEdge aGE(anE, aS, aC2d, aFPar, aLPar);
+
+      Standard_Real aParam = RealFirst();
+      const Standard_Real aDist = aGE.Distance3D(aP3d, 0, &aParam);
+      if((0.0 <= aDist) && (aDist <= theTol3D))
+      {
+        // It is necessary for periodic and quasi-periodic (e.g. sphere)
+        // surfaces (tests bug28211_18, bug28211_32, bug28211_33 and
+        // bug28211_35 in "tests/lowalgos/classifier/").
+        // E.g. if 2D-distance between theP and the p-curve of some edge
+        // is equal to T (the surface period) then 3D-point
+        // corresponding to theP can be exactly in the edge.
+        // So, 3D-distance is less than theTol3D however,
+        // returning ON-status is wrong in this case.
+        // Therefore, check in 2D-space is executed.
 
+        // ATTENTION!!!
+        // This check will be wrong if theTol3D covers the 2D-distance
+        // of the surface. I.e. if two 3D-points of any cylinder (for example)
+        // having 2D-coordinates (0, 0) and (PI, 0) can
+        // be considered as same with precision theTol3D.
+        // But for periodic surfaces, Check2D(...) method
+        // can return FALSE even if theTol3D is big
+        // (because this check is based on period value
+        // instead of tolerance).
 
+        gp_Pnt2d aPOnC;
+        if(Check2D(aGE, aParam, theP, theTol3D, aPOnC))
+        {
+          myState = TopAbs_ON;
+          myEdgeParameter = aParam;
+          myEdge = aGE;
+          return;
+        }
+      }
+    }
+  }
+#endif
+
+  // For information only.
+  // BRepClass_FaceClassifier works wrong with small faces
+  // (in 2D-space): UV-dimensions are less than 1.0e-5.
+  // See tests
+  //    boolean bopcommon_complex G5, boolean bopcut_complex H4,
+  //    boolean bopfuse_complex F7, G1, G2,
+  //    boolean boptuc_complex C2, C5, C6.
+
+  myFEx.Init(theF);
+  BRepClass_FClassifier::Perform(myFEx, theP, Precision::PConfusion());
+}
 
 //=======================================================================
 //function : Perform
 //purpose  : 
 //=======================================================================
-void  BRepClass_FaceClassifier::Perform(const TopoDS_Face& aF, 
-					const gp_Pnt& aP, 
-					const Standard_Real aTol)
+void  BRepClass_FaceClassifier::Perform(const TopoDS_Face& theF, 
+                                        const gp_Pnt& theP, 
+                                        const Standard_Real theTol3D)
 {
   Standard_Integer aNbExt, aIndice, i; 
   Standard_Real aU1, aU2, aV1, aV2, aMaxDist, aD;
@@ -97,14 +306,12 @@ void  BRepClass_FaceClassifier::Perform(const TopoDS_Face& aF,
   aMaxDist=RealLast();
   aIndice=0;
   //
-  BRepAdaptor_Surface aSurf(aF);
-  BRepTools::UVBounds(aF, aU1, aU2, aV1, aV2);
-  aExtrema.Initialize(aSurf, aU1, aU2, aV1, aV2, aTol, aTol);
+  BRepAdaptor_Surface aSurf(theF);
+  BRepTools::UVBounds(theF, aU1, aU2, aV1, aV2);
+  aExtrema.Initialize(aSurf, aU1, aU2, aV1, aV2,
+                        aSurf.UResolution(theTol3D), aSurf.VResolution(theTol3D));
   //
-  //modified by NIZNHY-PKV Wed Aug 13 11:28:47 2008f
-  rejected=Standard_True;
-  //modified by NIZNHY-PKV Wed Aug 13 11:28:49 2008t
-  aExtrema.Perform(aP);
+  aExtrema.Perform(theP);
   if(!aExtrema.IsDone()) {
     return;
   }
@@ -125,13 +332,194 @@ void  BRepClass_FaceClassifier::Perform(const TopoDS_Face& aF,
   if(aIndice) { 
     aExtrema.Point(aIndice).Parameter(aU1, aU2);
     aPuv.SetCoord(aU1, aU2);
-    Perform(aF, aPuv, aTol);
+    Perform(theF, aPuv, theTol3D);
+  }
+}
+
+//=======================================================================
+//function : DeltaUMax
+//purpose  : Returns maximal delta of U-parameter, which is permissible
+//            for returning ON-status.
+//           Returns negative value in case when this delta cannot be computed.
+//=======================================================================
+static Standard_Real DeltaUMax(const Adaptor3d_Surface &theAS)
+{
+  // As it is shown in lowalgos/classifier/bug28211_18,
+  // bug28211_32...bug28211_36, sometimes isolines
+  // U=0 and U=T/2 (where T is the period) are the same (in fact).
+  // Therefore, there is no point in returning T/2-value.
+  // Here, constant T/4 is chosen.
+
+  return theAS.IsUPeriodic() ? 0.25*theAS.UPeriod() : -1.0;
+}
+
+//=======================================================================
+//function : DeltaVMax
+//purpose  : Returns maximal delta of V-parameter, which is permissible
+//            for returning ON-status.
+//           Returns negative value in case when this delta cannot be computed.
+//=======================================================================
+static Standard_Real DeltaVMax(const Adaptor3d_Surface &theAS,
+                               const Standard_Real theTol3D)
+{
+  switch(theAS.GetType())
+  {
+    case GeomAbs_OffsetSurface:
+      //See lowalgos/classifier/bug28211_39 test case.
+      return DeltaVMax(theAS.BasisSurface()->Surface(), theTol3D);
+      Standard_FALLTHROUGH
+    case GeomAbs_Sphere:
+    case GeomAbs_SurfaceOfRevolution:
+      return theAS.VResolution(theTol3D);
+      Standard_FALLTHROUGH
+    default:
+      break;
+  }
+
+  // As it is shown in lowalgos/classifier/bug28211_18,
+  // bug28211_32...bug28211_36, sometimes isolines
+  // V=0 and V=T/2 (where T is the period) are the same (in fact).
+  // Therefore, there is no point in returning T/2-value.
+  // Here, constant T/4 is chosen.
+
+  return theAS.IsVPeriodic() ? 0.25*theAS.VPeriod() : -1.0;
+}
+
+#if 0
+//=======================================================================
+//function : Check2D
+//purpose  : Returns TRUE if theP and theProjPt are the same points
+//            with tolerance criterion.
+//=======================================================================
+Standard_Boolean Check2D(const TopoDS_Face &theTopF,
+                         const gp_Pnt2d& thePRef,
+                         const gp_Pnt2d& theProjPt,
+                         const Standard_Real theTol3D)
+{
+  const BRepAdaptor_Surface anAS(theTopF, Standard_False);
+
+  if(anAS.GetType() == GeomAbs_OtherSurface)
+    return Standard_False;
+
+  const Standard_Real aDU = Abs(theProjPt.X() - thePRef.X());
+  const Standard_Real aDUMax = DeltaUMax(anAS);
+  if((aDUMax >= 0.0) && (aDU > aDUMax))
+    return Standard_False;
+
+  const Standard_Real aDV = Abs(theProjPt.Y() - thePRef.Y());
+  const Standard_Real aDVMax = DeltaVMax(anAS, theTol3D);
+  if((aDVMax >= 0.0) && (aDV > aDVMax))
+    return Standard_False;
+
+  return Standard_True;
+}
+
+//=======================================================================
+//function : Check2D
+//purpose  : Returns TRUE if thePRef matches the point in the p-curve
+//            of theTopE on theTopF with parameter theCurvParam.
+//=======================================================================
+Standard_Boolean Check2D(const TopoDS_Edge &theTopE,
+                         const TopoDS_Face &theTopF,
+                         const Standard_Real theCurvParam,
+                         const gp_Pnt2d& thePRef,
+                         const Standard_Real theTol3D,
+                         const Standard_Boolean theIsOnClosedSurf)
+{
+  gp_Pnt2d aPOnC;
+  if(BRep_Tool::SameParameter(theTopE) && BRep_Tool::SameRange(theTopE))
+  {
+    Standard_Real aFPar, aLPar;
+    const Handle(Geom2d_Curve) aC1 = BRep_Tool::CurveOnSurface(theTopE, theTopF, aFPar, aLPar);
+    aC1->D0(theCurvParam, aPOnC);
+
+    // If theTopE is a seam-edge.
+    if(theIsOnClosedSurf)
+    {
+      const Handle(Geom2d_Curve) aC2 = BRep_Tool::CurveOnSurface(TopoDS::Edge(theTopE.Reversed()),
+                                                                 theTopF, aFPar, aLPar);
+
+      const gp_Pnt2d aPtemp(aC2->Value(theCurvParam));
+
+      if(thePRef.SquareDistance(aPtemp) < thePRef.SquareDistance(aPOnC))
+      {
+        aPOnC = aPtemp;
+      }
+    }
   }
+  else
+  {
+    TopClass_GeomEdge aGE(theTopE, theTopF);
+    const Standard_Real aDist = aGE.Distance2D(thePRef, &aPOnC);
+    if(aDist < 0.0)
+      return Standard_False;
+  }
+
+  return Check2D(theTopF, thePRef, aPOnC, theTol3D);
 }
 
+//=======================================================================
+//function : Check2D
+//purpose  : Returns TRUE if thePRef matches the point, which is
+//            2D-image of theTopV in theTopF.
+//=======================================================================
+Standard_Boolean Check2D(const TopoDS_Vertex &theTopV,
+                         const TopoDS_Face &theTopF,
+                         const gp_Pnt2d& thePRef,
+                         const Standard_Real theTol3D)
+{
+  const gp_Pnt2d aPt = BRep_Tool::Parameters(theTopV, theTopF);
+  return Check2D(theTopF, thePRef, aPt, theTol3D);
+}
 
+#else
+//=======================================================================
+//function : Check2D
+//purpose  : Returns TRUE if theP and thePRef are the same points.
+//           E.g. if X-coord of thePRef is equal to 0 and X-coord of theP
+//            is equal to T (the period of theSurf) then, most likely,
+//            theP and thePRef will be the same point in 3D-space.
+//           However, these points must be considered as different.
+//            It is made by this function.
+//           Another example why this function is useful is described in
+//            the test script "lowalgos/classifier/bug28211_18" (please see
+//            comment there).
+//=======================================================================
+Standard_Boolean Check2D(const TopClass_GeomEdge& theGE,
+                         const Standard_Real theCurvParam,
+                         const gp_Pnt2d& thePRef,
+                         const Standard_Real theTol3D,
+                         gp_Pnt2d& thePOnC)
+{
+  if(theGE.IsSameParameter())
+  {
+    const Geom2dAdaptor_Curve &aC = theGE.Get2DCurve();
+    aC.D0(theCurvParam, thePOnC);
+  }
+  else
+  {
+    const Standard_Real aDist = theGE.Distance2D(thePRef, &thePOnC);
+    if(aDist < 0.0)
+      return Standard_False;
+  }
+
+  const Adaptor3d_Surface &anAS = theGE.GetSurface();
 
+  if(anAS.GetType() == GeomAbs_OtherSurface)
+    return Standard_False;
 
+  const Standard_Real aDU = Abs(thePOnC.X() - thePRef.X());
+  const Standard_Real aDUMax = DeltaUMax(anAS);
+  if((aDUMax >= 0.0) && (aDU > aDUMax))
+    return Standard_False;
 
+  const Standard_Real aDV = Abs(thePOnC.Y() - thePRef.Y());
+  const Standard_Real aDVMax = DeltaVMax(anAS, theTol3D);
+  if((aDVMax >= 0.0) && (aDV > aDVMax))
+    return Standard_False;
+
+  return Standard_True;
+}
+#endif
 
 
diff --git a/src/BRepClass/BRepClass_FaceClassifier.hxx b/src/BRepClass/BRepClass_FaceClassifier.hxx
index 7bce028..9b65b57 100644
--- a/src/BRepClass/BRepClass_FaceClassifier.hxx
+++ b/src/BRepClass/BRepClass_FaceClassifier.hxx
@@ -21,9 +21,10 @@
 #include <Standard_DefineAlloc.hxx>
 #include <Standard_Handle.hxx>
 
+#include <BRepClass_FaceExplorer.hxx>
 #include <BRepClass_FClassifier.hxx>
 #include <Standard_Real.hxx>
-class BRepClass_FaceExplorer;
+
 class gp_Pnt2d;
 class TopoDS_Face;
 class gp_Pnt;
@@ -33,54 +34,42 @@ class gp_Pnt;
 class BRepClass_FaceClassifier  : public BRepClass_FClassifier
 {
 public:
-
   DEFINE_STANDARD_ALLOC
-
   
   //! Empty constructor, undefined algorithm.
   Standard_EXPORT BRepClass_FaceClassifier();
   
-  //! Creates an algorithm to classify the Point  P with
-  //! Tolerance <T> on the face described by <F>.
-  Standard_EXPORT BRepClass_FaceClassifier(BRepClass_FaceExplorer& F, const gp_Pnt2d& P, const Standard_Real Tol);
+  //! Creates an algorithm to classify the point theP relatively to
+  //! the face <theF> with 3D-tolerance <theTol3D> (used only for check ON-status).
+  Standard_EXPORT 
+    BRepClass_FaceClassifier(const TopoDS_Face& theF,
+                             const gp_Pnt2d& theP,
+                             const Standard_Real theTol3D);
   
-  //! Creates an algorithm to classify the Point  P with
-  //! Tolerance <T> on the face <F>.
-  Standard_EXPORT BRepClass_FaceClassifier(const TopoDS_Face& F, const gp_Pnt2d& P, const Standard_Real Tol);
+  //! Creates an algorithm to classify the point theP relatively to
+  //! the face <theF> with 3D-tolerance <theTol3D> (used only for check ON-status).
+  Standard_EXPORT BRepClass_FaceClassifier(const TopoDS_Face& theF,
+                                           const gp_Pnt& theP,
+                                           const Standard_Real theTol3D);
+
+  //! Classify the Point theP with 3D-tolerance <theTol3D> (used only for check ON-status)
+  //! relatively to the face <theF>.
+  Standard_EXPORT void Perform(const TopoDS_Face& theF,
+                               const gp_Pnt2d& theP,
+                               const Standard_Real theTol3D);
   
-  //! Classify  the Point  P  with  Tolerance <T> on the
-  //! face described by <F>.
-  Standard_EXPORT void Perform (const TopoDS_Face& F, const gp_Pnt2d& P, const Standard_Real Tol);
+  //! Classifies the point theP relatively to
+  //! the face <theF> with 3D-tolerance <theTol3D> (used only for check ON-status).
+  Standard_EXPORT void Perform(const TopoDS_Face& theF,
+                               const gp_Pnt& theP,
+                               const Standard_Real theTol3D);
   
-  //! Creates an algorithm to classify the Point  P with
-  //! Tolerance <T> on the face <F>.
-  Standard_EXPORT BRepClass_FaceClassifier(const TopoDS_Face& F, const gp_Pnt& P, const Standard_Real Tol);
-  
-  //! Classify  the Point  P  with  Tolerance <T> on the
-  //! face described by <F>.
-  Standard_EXPORT void Perform (const TopoDS_Face& F, const gp_Pnt& P, const Standard_Real Tol);
-
-
-
-
 protected:
-
-
-
-
+  
 
 private:
 
-
-
-
-
+  BRepClass_FaceExplorer myFEx;
 };
 
-
-
-
-
-
-
 #endif // _BRepClass_FaceClassifier_HeaderFile
diff --git a/src/BRepClass/BRepClass_FaceExplorer.cxx b/src/BRepClass/BRepClass_FaceExplorer.cxx
index 3fb9b5b..c55c653 100644
--- a/src/BRepClass/BRepClass_FaceExplorer.cxx
+++ b/src/BRepClass/BRepClass_FaceExplorer.cxx
@@ -1,4 +1,4 @@
-// Created on: 1992-11-19
+﻿// Created on: 1992-11-19
 // Created by: Remi LEQUETTE
 // Copyright (c) 1992-1999 Matra Datavision
 // Copyright (c) 1999-2014 OPEN CASCADE SAS
@@ -18,48 +18,224 @@
 //  Total rewriting of the method Segment; add the method OtherSegment.
 
 #include <BRep_Tool.hxx>
-#include <BRepClass_Edge.hxx>
 #include <BRepClass_FaceExplorer.hxx>
 #include <BRepTools.hxx>
+#include <BRepTools_WireExplorer.hxx>
 #include <Geom2d_Curve.hxx>
 #include <gp_Lin2d.hxx>
 #include <gp_Pnt2d.hxx>
 #include <Precision.hxx>
+#include <TopExp.hxx>
 #include <TopoDS.hxx>
 #include <TopoDS_Face.hxx>
-
-static const Standard_Real Probing_Start = 0.123;
-static const Standard_Real Probing_End = 0.7;
-static const Standard_Real Probing_Step = 0.2111;
+#include <TopoDS_Wire.hxx>
+#include <NCollection_Vector.hxx>
+#include <TopTools_MapOfShape.hxx>
+#include <NCollection_IncAllocator.hxx>
+#include <Geom2dAdaptor_Curve.hxx>
+#include <TopoDS_Vertex.hxx>
+#include <Geom2d_Line.hxx>
+#include <ElCLib.hxx>
+#include <Adaptor3d_CurveOnSurface.hxx>
+#include <Geom2dAdaptor_HCurve.hxx>
+#include <GeomAdaptor_HSurface.hxx>
+#include <TopClass_RayInfo.hxx>
+#include <Geom2dAdaptor_Curve.hxx>
+#include <TopClass_GeomVertex.hxx>
+
+static Standard_Real SquareDistanceOnPeriodic(const gp_Pnt2d &theP1,
+                                              const gp_Pnt2d &theP2,
+                                              const Standard_Real theUPeriod,
+                                              const Standard_Real theVPeriod);
+
+static Standard_Boolean MyUVPoints(const TopoDS_Edge& theE,
+                                   const TopoDS_Face& theF,
+                                   gp_Pnt2d& thePFirst,
+                                   gp_Pnt2d& thePLast);
+
+
+const Standard_Real BRepClass_FaceExplorer::myProbing_Start = 0.123;
+const Standard_Real BRepClass_FaceExplorer::myProbing_End = 0.7;
+const Standard_Real BRepClass_FaceExplorer::myProbing_Step = 0.2111;
 
 //=======================================================================
 //function : BRepClass_FaceExplorer
 //purpose  : 
 //=======================================================================
+BRepClass_FaceExplorer::BRepClass_FaceExplorer(const TopoDS_Face& theF)
+  : myBoundsComputed(Standard_False),
+    myUMin(0.), myUMax(0.), myVMin(0.), myVMax(0.),
+    myCurEdgeInd(0), myCurEdgePar(0.)
+
+{
+  Init(theF);
+}
 
-BRepClass_FaceExplorer::BRepClass_FaceExplorer(const TopoDS_Face& F) :
-       myFace(F),
-       myCurEdgeInd(1),
-       myCurEdgePar(Probing_Start)
+//=======================================================================
+//function : Init
+//purpose  : BRepTools_WireExplorer works better with
+//            and more reliable with FORWARD-oriented face.
+//=======================================================================
+void BRepClass_FaceExplorer::Init(const TopoDS_Face& theF)
 {
-  myFace.Orientation(TopAbs_FORWARD);
+  if (myFace.IsSame(theF))
+  {
+    //The classifier has already been initialized.
+    return;
+  }
+
+  myMapWE.Clear();
+
+  myFace = TopoDS::Face(theF.Oriented(TopAbs_FORWARD));
+  Handle(NCollection_IncAllocator) anAlloc = new NCollection_IncAllocator;
+  mySurf = BRep_Tool::Surface(myFace);
+  GeomAdaptor_Surface anAdS(mySurf);
+
+  const Standard_Real aUPeriod = anAdS.IsUPeriodic() ? anAdS.UPeriod() : 0.0;
+  const Standard_Real aVPeriod = anAdS.IsVPeriodic() ? anAdS.VPeriod() : 0.0;
+
+  for (TopoDS_Iterator anExpW(myFace); anExpW.More(); anExpW.Next())
+  {
+    if (anExpW.Value().ShapeType() == TopAbs_WIRE)
+    {
+      const TopoDS_Wire &aWir = TopoDS::Wire(anExpW.Value());
+      NCollection_List<TopClass_GeomEdge> anEList(anAlloc);
+      myMapWE.Add(aWir, anEList);
+    }
+  }
+
+  if (myMapWE.IsEmpty())
+    return;
+
+  TopTools_IndexedDataMapOfShapeListOfShape aMapVE;
+  TopExp::MapShapesAndUniqueAncestors(myFace, TopAbs_VERTEX, TopAbs_EDGE, aMapVE);
+
+  InitWires();
+
+  for (; myWExplorer.More(); myWExplorer.Next())
+  {
+    const TopoDS_Wire &aWir = TopoDS::Wire(myWExplorer.Key());
+    NCollection_List<TopClass_GeomEdge>& anEList = myWExplorer.ChangeValue();
+    anEList.Clear();
+
+    BRepTools_WireExplorer anExp(aWir, myFace);
+
+    TopoDS_Edge anE1 = anExp.Current(), aFirstEdge, aLastEdge;
+
+    if (anE1.IsNull())
+    {
+      // It is possible if aWir contains
+      // only INTERNAL/EXTERNAL edges.
+
+      continue;
+    }
+
+    aFirstEdge = anE1;
+    SimpleAdd(anE1);
+    anExp.Next();
+
+    if (!anExp.More())
+    {
+      // The wire contains only single edge.
+      // But this edge can be closed itself (e.g. circle).
+
+      TopoDS_Vertex aVf, aVl;
+      TopExp::Vertices(anE1, aVf, aVl);
+      if (!aVf.IsNull() && aVf.IsSame(aVl))
+        AddPseudo(anE1, anE1, aVf.IsNull() ? aVl : aVf, aUPeriod, aVPeriod);
+
+      continue;
+    }
+
+    for (; anExp.More(); anExp.Next())
+    {
+      const TopoDS_Edge& anE2 = anExp.Current();
+      aLastEdge = anE2;
+      SimpleAdd(anE2);
+
+      const TopoDS_Vertex &aVertCurr = anExp.CurrentVertex();
+      AddPseudo(anE1, anE2, aVertCurr, aUPeriod, aVPeriod);
+      anE1 = anE2;
+    }
+
+    if (aFirstEdge.IsNull() || aLastEdge.IsNull())
+      continue;
+
+    //TopExp::CommonVertex(...) does not work
+    //if edges have more than one pair of common vertex
+    //(e.g. two halves of circle). Here, we process this case.
+    TopoDS_Vertex aV[4];
+    TopExp::Vertices(aFirstEdge, aV[0], aV[1]);
+    if (!aV[0].IsNull() && aV[0].IsSame(aV[1]))
+    {
+      // Possible reason is the NOT-CLOSED edge
+      // has only single vertex and is covered by it.
+      // Pseudo-edge is not added and this case is invalid.
+      continue;
+    }
+
+    TopExp::Vertices(aLastEdge, aV[2], aV[3]);
+    if (!aV[2].IsNull() && aV[2].IsSame(aV[3]))
+    {
+      // Possible reason is the NOT-CLOSED edge
+      // has only single vertex and is covered by it.
+      // Pseudo-edge is not added and this case is invalid.
+      continue;
+    }
+
+    for (Standard_Integer anIDFE = 0; anIDFE < 2; anIDFE++)
+    {
+      for (Standard_Integer anIDLE = 2; anIDLE < 4; anIDLE++)
+      {
+        if (!aV[anIDFE].IsSame(aV[anIDLE]))
+          continue;
+
+        const NCollection_List<TopoDS_Shape> *anEList = aMapVE.Seek(aV[anIDFE]);
+        if ((anEList != 0) && (anEList->Extent() > 2))
+        {
+          // Causes:
+          //  1. Non-manifold topology.
+          //  2. Case such as:
+          //
+          //        *************************
+          //        *                       *
+          //  seam  *                       *  seam
+          //        *  edge1         edge2  *
+          //        * ********    ********* *
+          //       V1        V2   V3       V4
+          //
+          //
+          //  V1 - vertex between edge1 and seam
+          //  V4 - vertex between edge2 and seam
+          //
+          //  Indeed, V1 and V4 are same but they
+          //  must not be joined.
+
+          continue;
+        }
+
+
+        AddPseudo(aFirstEdge, aLastEdge, aV[anIDFE], aUPeriod, aVPeriod);
+      }
+    }
+  }
+
+  //InitWires();
+  //InitEdges();
 }
 
 //=======================================================================
 //function : CheckPoint
 //purpose  : 
 //=======================================================================
-
 Standard_Boolean  BRepClass_FaceExplorer::CheckPoint(gp_Pnt2d& thePoint)
 {
   Standard_Real anUMin = 0.0, anUMax = 0.0, aVMin = 0.0, aVMax = 0.0;
-  TopLoc_Location aLocation;
-  const Handle(Geom_Surface)& aSurface = BRep_Tool::Surface(myFace, aLocation);
-  aSurface->Bounds(anUMin, anUMax, aVMin, aVMax);
+  mySurf->Bounds(anUMin, anUMax, aVMin, aVMax);
   if (Precision::IsInfinite(anUMin) || Precision::IsInfinite(anUMax) ||
       Precision::IsInfinite(aVMin) || Precision::IsInfinite(aVMax))
   {
-    BRepTools::UVBounds(myFace, anUMin, anUMax, aVMin, aVMax);
+    UVBounds(anUMin, anUMax, aVMin, aVMax);
     if (Precision::IsInfinite(anUMin) || Precision::IsInfinite(anUMax) ||
         Precision::IsInfinite(aVMin) || Precision::IsInfinite(aVMax))
     {
@@ -91,192 +267,470 @@ Standard_Boolean  BRepClass_FaceExplorer::CheckPoint(gp_Pnt2d& thePoint)
 }
 
 //=======================================================================
-//function : Reject
+//function : ListOfRays
 //purpose  : 
 //=======================================================================
-
-Standard_Boolean  BRepClass_FaceExplorer::Reject(const gp_Pnt2d&)const 
+Standard_Boolean BRepClass_FaceExplorer::OtherRay(const gp_Pnt2d& theP,
+                                                  TopClass_RayInfo& theRay,
+                                                  const unsigned int theMaxRating)
 {
+#define NextSegmentMacro {myCurEdgeInd++; myCurEdgePar = myProbing_Start; continue;}
+
+  const Standard_Real aTolParConf2 = Precision::SquarePConfusion();
+  Standard_Real       aFPar, aLPar;
+
+  gp_Dir2d aLinDir;
+  Standard_Integer i = 1;
+  for(TopoDS_Iterator aWExp(myFace); aWExp.More(); aWExp.Next())
+  {
+    // aWire is wire
+    const TopoDS_Shape &aWire = aWExp.Value();
+    for(TopoDS_Iterator anEExp(aWire); anEExp.More(); anEExp.Next(), i++)
+    {
+      if(i > myCurEdgeInd)
+        return Standard_False;
+
+      if(i != myCurEdgeInd)
+        continue;
+
+      if(myCurEdgePar >= myProbing_End)
+      {
+        NextSegmentMacro;
+      }
+
+      const TopoDS_Edge &anEdge = TopoDS::Edge(anEExp.Value());
+      const TopAbs_Orientation anOrientation = anEdge.Orientation();
+
+      if((anOrientation != TopAbs_FORWARD) &&
+         (anOrientation != TopAbs_REVERSED))
+      {
+        NextSegmentMacro;
+      }
+
+      const Handle(Geom2d_Curve) aC2d = BRep_Tool::CurveOnSurface(anEdge,
+                                                                  myFace,
+                                                                  aFPar,
+                                                                  aLPar);
+
+      if(aC2d.IsNull())
+      {
+        NextSegmentMacro;
+      }
+
+      // Treatment of infinite cases.
+      if(Precision::IsNegativeInfinite(aFPar))
+      {
+        if(Precision::IsPositiveInfinite(aLPar))
+        {
+          aFPar = -1.;
+          aLPar = 1.;
+        }
+        else
+        {
+          aFPar = aLPar - 1.;
+        }
+      }
+      else if(Precision::IsPositiveInfinite(aLPar))
+      {
+        aLPar = aFPar + 1.;
+      }
+
+      for(; myCurEdgePar < myProbing_End; myCurEdgePar += myProbing_Step)
+      {
+        TopClass_RayInfo aRI;
+        aLinDir.SetCoord(1.0, 0.0);
+
+        const Standard_Real aParamIn = myCurEdgePar*aFPar + (1. - myCurEdgePar)*aLPar;
+
+        gp_Pnt2d aPOnC;
+        gp_Vec2d aTanVec;
+        aC2d->D1(aParamIn, aPOnC, aTanVec);
+
+        const Standard_Real aPrmTemp = aPOnC.SquareDistance(theP);
+        if(aPrmTemp > aTolParConf2)
+        {
+          aLinDir.SetXY(aPOnC.XY() - theP.XY());
+          Standard_Real aTanMod = aTanVec.SquareMagnitude();
+          if(aTanMod < aTolParConf2)
+          {
+            aRI.AddPenalty(10);
+          }
+          else
+          {
+            const Standard_Real aSinA = Abs(aTanVec.Crossed(aLinDir.XY())) / Sqrt(aTanMod);
+            // The line from the input point P to the current point on edge
+            // is tangent to the edge curve. This condition is bad for classification.
+            // Therefore, we add penalty for this ray.
+
+            if(aSinA < 0.001)
+            {
+              aRI.AddPenalty(3);
+            }
+            else if(aSinA < 0.02)
+            {
+              aRI.AddPenalty(2);
+            }
+            else if(aSinA < 0.1)
+            {
+              aRI.AddPenalty(1);
+            }
+          }
+        }
+        else
+        {
+          aRI.AddPenalty(10);
+        }
+
+        if(aRI.GetWeight() < theMaxRating)
+        {
+          aRI.SetLin(gp_Lin2d(theP, aLinDir));
+          aRI.SetParameter(Sqrt(aPrmTemp));
+
+          theRay = aRI;
+          myCurEdgePar += myProbing_Step;
+          return Standard_True;
+        }
+      }// for (; myCurEdgePar < ...
+
+      NextSegmentMacro;
+    }//for(TopoDS_Iterator anEExp(aWire) ...
+  } //for(TopoDS_Iterator aWExp(myFace) ...
+
   return Standard_False;
+
+#undef NextSegmentMacro
 }
 
 //=======================================================================
-//function : Segment
+//function : InitWires
 //purpose  : 
 //=======================================================================
 
-Standard_Boolean BRepClass_FaceExplorer::Segment(const gp_Pnt2d& P, 
-						 gp_Lin2d& L,
-						 Standard_Real& Par)
+void  BRepClass_FaceExplorer::InitWires()
 {
-  myCurEdgeInd = 1;
-  myCurEdgePar = Probing_Start;
-
-  return OtherSegment(P, L, Par);
+  myWExplorer = NCollection_IndexedDataMap<TopoDS_Wire,
+                      NCollection_List<TopClass_GeomEdge>>::Iterator(myMapWE);
 }
 
 //=======================================================================
-//function : OtherSegment
+//function : SimpleAdd
 //purpose  : 
 //=======================================================================
+void BRepClass_FaceExplorer::SimpleAdd(const TopoDS_Edge &theEdge)
+{
+#ifdef BREPCLASS_FACEEXPLORER_DEBUG
+  {
+    std::cout << "BRepClass_FaceExplorer::SimpleAdd(...) DEBUG " << std::endl;
+    std::cout << "Edge orientation (0F, 1R, 2I, 3E) == " << 
+                                          theEdge.Orientation() << std::endl;
+
+    gp_Pnt2d aPF, aPL;
+    MyUVPoints(theEdge, myFace, aPF, aPL);
 
-Standard_Boolean BRepClass_FaceExplorer::OtherSegment(const gp_Pnt2d& P, 
-						      gp_Lin2d& L,
-						      Standard_Real& Par)
+    std::cout << "PF(" <<aPF.X() << ", " << aPF.Y() << ")" << std::endl;
+    std::cout << "PL(" <<aPL.X() << ", " << aPL.Y() << ")" << std::endl;
+  }
+#endif
+
+  Standard_Real aFPar, aLPar;
+  const Handle(Geom2d_Curve) aC2d = BRep_Tool::CurveOnSurface(theEdge, myFace, aFPar, aLPar);
+  const TopClass_GeomEdge aGE(theEdge, mySurf, aC2d, aFPar, aLPar);
+
+  if (aGE.IsNull())
+    return;
+
+  NCollection_List<TopClass_GeomEdge>& anEList = myWExplorer.ChangeValue();
+  anEList.Append(aGE);
+}
+
+//=======================================================================
+//function : AddPseudo
+//purpose  : 
+//=======================================================================
+void BRepClass_FaceExplorer::AddPseudo(const TopoDS_Edge& theE1,
+                                       const TopoDS_Edge& theE2,
+                                       const TopoDS_Vertex& theV,
+                                       const Standard_Real theUPeriod,
+                                       const Standard_Real theVPeriod)
 {
-  TopExp_Explorer      anExpF(myFace,TopAbs_EDGE);
-  Standard_Integer     i;
-  Standard_Real        aFPar;
-  Standard_Real        aLPar;
-  Handle(Geom2d_Curve) aC2d;
-  Standard_Real        aTolParConf2 = Precision::PConfusion() * Precision::PConfusion();
-  gp_Pnt2d             aPOnC;
-  Standard_Real        aParamIn;
-
-  for (i = 1; anExpF.More(); anExpF.Next(), i++) {
-    if (i != myCurEdgeInd)
-      continue;
+  gp_Pnt2d aPFirst, aPLast;
+  TopAbs_Orientation anOriFirst = theE1.Orientation(), anOriLast = theE2.Orientation();
 
-    const TopoDS_Shape       &aLocalShape   = anExpF.Current();
-    const TopAbs_Orientation  anOrientation = aLocalShape.Orientation();
-
-    if (anOrientation == TopAbs_FORWARD || anOrientation == TopAbs_REVERSED) {
-      const TopoDS_Edge &anEdge = TopoDS::Edge(aLocalShape);
-
-      aC2d = BRep_Tool::CurveOnSurface(anEdge, myFace, aFPar, aLPar);
-
-      if (!aC2d.IsNull()) {
-	// Treatment of infinite cases.
-	if (Precision::IsNegativeInfinite(aFPar)) {
-	  if (Precision::IsPositiveInfinite(aLPar)) {
-	    aFPar = -1.;
-	    aLPar =  1.;
-	  } else {
-	    aFPar = aLPar - 1.;
-	  }
-	} else if (Precision::IsPositiveInfinite(aLPar))
-	  aLPar = aFPar + 1.;
-
-	for (; myCurEdgePar < Probing_End ;myCurEdgePar += Probing_Step) {
-	  aParamIn = myCurEdgePar*aFPar + (1. - myCurEdgePar)*aLPar;
-
-          gp_Vec2d aTanVec;
-	  aC2d->D1(aParamIn, aPOnC, aTanVec);
-	  Par = aPOnC.SquareDistance(P);
-
-	  if (Par > aTolParConf2) {
-	    gp_Vec2d aLinVec(P, aPOnC);
-	    gp_Dir2d aLinDir(aLinVec);
-
-            Standard_Real aTanMod = aTanVec.SquareMagnitude();
-            if (aTanMod < aTolParConf2)
-              continue;
-            aTanVec /= Sqrt(aTanMod);
-            Standard_Real aSinA = aTanVec.Crossed(aLinDir.XY());
-            const Standard_Real SmallAngle = 0.001;
-            if (Abs(aSinA) < SmallAngle)
-            {
-              // The line from the input point P to the current point on edge
-              // is tangent to the edge curve. This condition is bad for classification.
-              // Therefore try to go to another point in the hope that there will be 
-              // no tangent. If there tangent is preserved then leave the last point in 
-              // order to get this edge chanse to participate in classification.
-              if (myCurEdgePar + Probing_Step < Probing_End)
-                continue;
-            }
+  if ((anOriFirst != TopAbs_FORWARD) && (anOriFirst != TopAbs_REVERSED))
+    return;
 
-	    L = gp_Lin2d(P, aLinDir);
+  if ((anOriLast != TopAbs_FORWARD) && (anOriLast != TopAbs_REVERSED))
+    return;
 
-	    // Check if ends of a curve lie on a line.
-	    aC2d->D0(aFPar, aPOnC);
+  Standard_Boolean isSame = Standard_False;
 
-	    if (L.SquareDistance(aPOnC) > aTolParConf2) {
-	      aC2d->D0(aLPar, aPOnC);
+  if (theE1.IsEqual(theE2))
+  {
+    // source Wire contains single edge only
+    // with single vertex but the edge can be
+    // geometrically not-closed (e.g. the part
+    // of some circle).
+    // BRep_Tool::UVPoints(...) returns equal points for this case. It is inappropriate.
+
+    // The algorithm below will create a pseudo-edge
+    // from aPFirst to aPLast.
+    // But in this case it must join end-point of curve
+    // with its start-point (exactly in this direction).
+    if (!MyUVPoints(TopoDS::Edge(theE1.Oriented(TopAbs_FORWARD)),
+                    myFace, aPLast, aPFirst))
+      return;
+  }
+  else
+  {
+    if (theE1.IsSame(theE2))
+    {
+      //Gap between two seam-edges (e.g. cylinder without bottom-base).
+      //P-curve is (no 2D-curve is bottom)
+      //
+      //          ****************
+      //          *              *
+      //    seam  *              * seam
+      //          *              *
+      //          *              *
+
+      isSame = Standard_True;
+    }
 
-	      if (L.SquareDistance(aPOnC) > aTolParConf2) {
-		myCurEdgePar += Probing_Step;
+    if (!PrepareEdge(theE1, theV, aPFirst, anOriFirst))
+    {
+      return;
+    }
 
-		if (myCurEdgePar >= Probing_End) {
-		  myCurEdgeInd++;
-		  myCurEdgePar = Probing_Start;
-		}
+    if ((anOriFirst != TopAbs_FORWARD) && (anOriFirst != TopAbs_REVERSED))
+      return;
 
-		Par = Sqrt(Par);
-		return Standard_True;
-	      }
-	    }
-	  }
-	}
-      } // if (!aC2d.IsNull()) {
-    } // if (anOrientation == TopAbs_FORWARD ...
+    if (!PrepareEdge(theE2, theV, aPLast, anOriLast))
+      return;
+  }
 
-    // This curve is not valid for line construction. Go to another edge.
-    myCurEdgeInd++;
-    myCurEdgePar = Probing_Start;
+  if ((anOriLast != TopAbs_FORWARD) && (anOriLast != TopAbs_REVERSED))
+    return;
+
+  if (!isSame)
+  {
+    if(SquareDistanceOnPeriodic(aPFirst, aPLast,
+                               theUPeriod, theVPeriod) < Precision::SquarePConfusion())
+    {
+      return;
+    }
+  }
+  else if(aPFirst.SquareDistance(aPLast) < Precision::SquarePConfusion())
+  {
+    return;
   }
 
-  // nothing found, return an horizontal line
-  Par = RealLast();
-  L   = gp_Lin2d(P,gp_Dir2d(1,0));
+#ifdef BREPCLASS_FACEEXPLORER_DEBUG
+  {
+    std::cout << "BRepClass_FaceExplorer::AddPseudo(...) DEBUG " << std::endl;
+    std::cout << "Edge orientation (0F, 1R, 2I, 3E) == " << anOriLast << std::endl;
 
-  return Standard_False;
+    std::cout << "PF(" << aPFirst.X() << ", " << aPFirst.Y() << ")" << std::endl;
+    std::cout << "PL(" << aPLast.X() << ", " << aPLast.Y() << ")" << std::endl;
+  }
+#endif
+
+  const gp_XY aMVec = aPLast.XY() - aPFirst.XY();
+  gp_Lin2d aLin(aPFirst, gp_Dir2d(aMVec));
+  const Standard_Real aFPar = 0.0;
+  const Standard_Real aLPar = aMVec.Modulus();
+  const Handle(Geom2d_Curve) aPseudoEdge = new Geom2d_Line(aLin);
+
+  // Null 3D-curve
+  Handle(Geom_Curve) aC3d;
+
+  // Pseudo-edge. Therefore, parameter of the vertex is not important value.
+  TopClass_GeomVertex aV(theV, aFPar);
+
+  TopClass_GeomEdge aGE(aC3d, aPseudoEdge, mySurf,
+                        aFPar, aLPar, anOriLast, aV, aV, Standard_False);
+
+  NCollection_List<TopClass_GeomEdge>& anEList = myWExplorer.ChangeValue();
+  anEList.Append(aGE);
 }
 
 //=======================================================================
-//function : InitWires
+//function : PrepareEdge
 //purpose  : 
 //=======================================================================
-
-void  BRepClass_FaceExplorer::InitWires()
+Standard_Boolean BRepClass_FaceExplorer::PrepareEdge(const TopoDS_Edge& theEdge,
+                                                     const TopoDS_Vertex& theV,
+                                                     gp_Pnt2d& thePnt,
+                                                     TopAbs_Orientation& theOri)
 {
-  myWExplorer.Init(myFace,TopAbs_WIRE);
+  const TopAbs_Orientation anOri = theEdge.Orientation();
+  if ((anOri != TopAbs_FORWARD) && (anOri != TopAbs_REVERSED))
+    return Standard_False;
+
+  TopoDS_Vertex aVFirst, aVLast;
+  TopExp::Vertices(theEdge, aVFirst, aVLast, Standard_True);
+
+  if (!aVFirst.IsNull() && aVFirst.IsSame(theV))
+  {
+    gp_Pnt2d aPtemp;
+    if (anOri == TopAbs_FORWARD)
+    {
+      if (!MyUVPoints(theEdge, myFace, thePnt, aPtemp))
+        return Standard_False;
+    }
+    else //if(anOri == TopAbs_REVERSED)
+    {
+      if (!MyUVPoints(theEdge, myFace, aPtemp, thePnt))
+        return Standard_False;
+    }
+    theOri = TopAbs_FORWARD;// aVFirst.Orientation();
+  }
+  else if (!aVLast.IsNull() && aVLast.IsSame(theV))
+  {
+    gp_Pnt2d aPtemp;
+
+    if (anOri == TopAbs_FORWARD)
+    {
+      if (!MyUVPoints(theEdge, myFace, aPtemp, thePnt))
+        return Standard_False;
+    }
+    else //if(anOri == TopAbs_REVERSED)
+    {
+      if (!MyUVPoints(theEdge, myFace, thePnt, aPtemp))
+        return Standard_False;
+    }
+    theOri = TopAbs_REVERSED;//aVLast.Orientation();
+  }
+  else
+  {
+    return Standard_False;
+  }
+
+  return Standard_True;
 }
 
 //=======================================================================
-//function : RejectWire NYI
+//function : InitEdges
 //purpose  : 
 //=======================================================================
-
-Standard_Boolean  BRepClass_FaceExplorer::RejectWire
-  (const gp_Lin2d& , 
-   const Standard_Real)const 
+void BRepClass_FaceExplorer::InitEdges()
 {
-  return Standard_False;
+  NCollection_List<TopClass_GeomEdge>& anEList = myWExplorer.ChangeValue();
+  myEExplorer.Initialize(anEList);
 }
 
 //=======================================================================
-//function : InitEdges
+//function : CurrentEdge
 //purpose  : 
 //=======================================================================
-
-void  BRepClass_FaceExplorer::InitEdges()
+void BRepClass_FaceExplorer::CurrentEdge(TopClass_GeomEdge& theGE) const
 {
-  myEExplorer.Init(myWExplorer.Current(),TopAbs_EDGE);
+  theGE = myEExplorer.Value();
 }
 
 //=======================================================================
-//function : RejectEdge NYI
+//function : IsPointInVertex
 //purpose  : 
 //=======================================================================
-
-Standard_Boolean  BRepClass_FaceExplorer::RejectEdge
-  (const gp_Lin2d& , 
-   const Standard_Real )const 
+Standard_Boolean BRepClass_FaceExplorer::
+                    IsPointInEdgeVertex(const gp_Pnt2d &thePnt,
+                                        Standard_Real* const theParameter) const
 {
+  const gp_Pnt aPref(mySurf->Value(thePnt.X(), thePnt.Y()));
+  const TopClass_GeomEdge &anEdge = myEExplorer.Value();
+
+  if (anEdge.FirstVertex().IsSame(aPref))
+  {
+    if (theParameter)
+      *theParameter = anEdge.FirstVertex().ParameterOnEdge();
+
+    return Standard_True;
+  }
+
+  if (anEdge.LastVertex().IsSame(aPref))
+  {
+    if (theParameter)
+      *theParameter = anEdge.LastVertex().ParameterOnEdge();
+
+    return Standard_True;
+  }
+
+  if (theParameter)
+    *theParameter = 0.0;
+
   return Standard_False;
 }
 
-
 //=======================================================================
-//function : CurrentEdge
+//function : UVBounds
 //purpose  : 
 //=======================================================================
+void BRepClass_FaceExplorer::UVBounds(Standard_Real& theUMin, Standard_Real& theUMax,
+                                      Standard_Real& theVMin, Standard_Real& theVMax) const
+{
+  if (!myBoundsComputed)
+  {
+    BRepTools::UVBounds(myFace, myUMin, myUMax, myVMin, myVMax);
+    myBoundsComputed = Standard_True;
+  }
+  theUMin = myUMin;
+  theUMax = myUMax;
+  theVMin = myVMin;
+  theVMax = myVMax;
+}
 
-void  BRepClass_FaceExplorer::CurrentEdge(BRepClass_Edge& E, 
-					  TopAbs_Orientation& Or) const 
+//=======================================================================
+//function : SquareDistanceOnPeriodic
+//purpose  : Computes the distance between two 2D-points in case if they
+//            are in different periodic regions or in same region but near
+//            to the different period boundary. I.e. (example on 1D-object
+//            with period T):
+//            1. Square distance between points X and (X+d+k*T)
+//                (k is an integer number) is equal to d^2 
+//                (instead of (d+k*T)^2).
+//            2. Square distance between points X and T-Y 
+//                (0 <= X <= T, 0 <= Y <= T) is equal to (X+Y)^2 instead of
+//                (T-Y-X)^2.
+//=======================================================================
+Standard_Real SquareDistanceOnPeriodic(const gp_Pnt2d &theP1,
+                                       const gp_Pnt2d &theP2,
+                                       const Standard_Real theUPeriod,
+                                       const Standard_Real theVPeriod)
 {
-  E.Edge() = TopoDS::Edge(myEExplorer.Current());
-  E.Face() = myFace;
-  Or = E.Edge().Orientation();
+  const Standard_Real aDeltaXtmp = theUPeriod > 0.0 ?
+                                      fmod(Abs(theP1.X() - theP2.X()), theUPeriod) :
+                                      Abs(theP1.X() - theP2.X());
+
+  const Standard_Real aDeltaYtmp = theVPeriod > 0.0 ?
+                                      fmod(Abs(theP1.Y() - theP2.Y()), theVPeriod) :
+                                      Abs(theP1.Y() - theP2.Y());
+  const Standard_Real aDeltaX = Min(aDeltaXtmp, Abs(aDeltaXtmp - theUPeriod));
+  const Standard_Real aDeltaY = Min(aDeltaYtmp, Abs(aDeltaYtmp - theVPeriod));
+
+  return (aDeltaX*aDeltaX + aDeltaY*aDeltaY);
 }
 
+//=======================================================================
+//function : MyUVPoints
+//purpose  : Does the same as BRep_Tool::UVPoints but returns
+//            first and last points of 2d-curves (not UV-points of edge vertices).
+//=======================================================================
+Standard_Boolean MyUVPoints(const TopoDS_Edge& theE,
+                const TopoDS_Face& theF,
+                gp_Pnt2d& thePFirst,
+                gp_Pnt2d& thePLast)
+{
+  Standard_Real aFirst = 1.0, aLast = -1.0;
+
+  // Direction of aC does not take into account
+  // the orientation of the edge.
+  const Handle(Geom2d_Curve) aC = BRep_Tool::CurveOnSurface(theE,
+                                                            theF,
+                                                            aFirst,
+                                                            aLast);
+  if (aC.IsNull())
+    return Standard_False;
+
+  aC->D0(aFirst, thePFirst);
+  aC->D0(aLast, thePLast);
+  return Standard_True;
+}
diff --git a/src/BRepClass/BRepClass_FaceExplorer.hxx b/src/BRepClass/BRepClass_FaceExplorer.hxx
index 3e404b8..be0ba68 100644
--- a/src/BRepClass/BRepClass_FaceExplorer.hxx
+++ b/src/BRepClass/BRepClass_FaceExplorer.hxx
@@ -17,21 +17,15 @@
 #ifndef _BRepClass_FaceExplorer_HeaderFile
 #define _BRepClass_FaceExplorer_HeaderFile
 
-#include <Standard.hxx>
-#include <Standard_DefineAlloc.hxx>
-#include <Standard_Handle.hxx>
-
-#include <TopoDS_Face.hxx>
+#include <NCollection_Vector.hxx>
+#include <TopClass_GeomEdge.hxx>
 #include <TopExp_Explorer.hxx>
-#include <Standard_Integer.hxx>
-#include <Standard_Real.hxx>
-#include <Standard_Boolean.hxx>
-#include <TopAbs_Orientation.hxx>
-class TopoDS_Face;
-class gp_Pnt2d;
-class gp_Lin2d;
-class BRepClass_Edge;
+#include <TopoDS_Face.hxx>
+#include <TopoDS_Wire.hxx>
+#include <NCollection_List.hxx>
+#include <NCollection_IndexedDataMap.hxx>
 
+class TopClass_RayInfo;
 
 //! Provide an   exploration of a  BRep Face   for the
 //! classification. Return UV edges.
@@ -41,29 +35,23 @@ public:
 
   DEFINE_STANDARD_ALLOC
 
-  
-  Standard_EXPORT BRepClass_FaceExplorer(const TopoDS_Face& F);
+  //! Constructor
+  Standard_EXPORT BRepClass_FaceExplorer(const TopoDS_Face& theF);
 
-  //! Checks the point and change its coords if it is located too far
+  //! Initializes <this>
+  Standard_EXPORT void Init(const TopoDS_Face& theF);
+
+  //! Checks the point and change its coordinates if it is located too far
   //! from the bounding box of the face. New Coordinates of the point 
   //! will be on the line between the point and the center of the 
   //! bounding box. Returns True if point was not changed.
-  Standard_EXPORT Standard_Boolean CheckPoint (gp_Pnt2d& thePoint);
-  
-  //! Should  return  True  if the  point  is  outside a
-  //! bounding volume of the face.
-  Standard_EXPORT Standard_Boolean Reject (const gp_Pnt2d& P) const;
-  
-  //! Returns  in <L>, <Par>  a segment having at least
-  //! one  intersection  with  the   face  boundary  to
-  //! compute  intersections.
-  Standard_EXPORT Standard_Boolean Segment (const gp_Pnt2d& P, gp_Lin2d& L, Standard_Real& Par);
-  
-  //! Returns  in <L>, <Par>  a segment having at least
-  //! one  intersection  with  the   face  boundary  to
-  //! compute  intersections. Each call gives another segment.
-  Standard_EXPORT Standard_Boolean OtherSegment (const gp_Pnt2d& P, gp_Lin2d& L, Standard_Real& Par);
-  
+  Standard_EXPORT Standard_Boolean CheckPoint(gp_Pnt2d& thePoint);
+
+  //! Returns ray to process.
+  Standard_EXPORT Standard_Boolean OtherRay(const gp_Pnt2d& theP,
+                                            TopClass_RayInfo& theRay,
+                                            const unsigned int theMaxRating);
+
   //! Starts an exploration of the wires.
   Standard_EXPORT void InitWires();
   
@@ -71,56 +59,137 @@ public:
     Standard_Boolean MoreWires() const;
   
   //! Sets the explorer  to the  next  wire.
-    void NextWire();
-  
-  //! Returns True  if the wire  bounding volume does not
-  //! intersect the segment.
-  Standard_EXPORT Standard_Boolean RejectWire (const gp_Lin2d& L, const Standard_Real Par) const;
-  
+  void NextWire();
+
   //! Starts an exploration of the  edges of the current
   //! wire.
   Standard_EXPORT void InitEdges();
   
   //! Returns True if there is a current edge.
-    Standard_Boolean MoreEdges() const;
-  
+  Standard_Boolean MoreEdges() const;
+
   //! Sets the explorer  to the  next  edge.
-    void NextEdge();
-  
-  //! Returns True  if the edge  bounding volume does not
-  //! intersect the segment.
-  Standard_EXPORT Standard_Boolean RejectEdge (const gp_Lin2d& L, const Standard_Real Par) const;
-  
-  //! Current edge in current wire and its orientation.
-  Standard_EXPORT void CurrentEdge (BRepClass_Edge& E, TopAbs_Orientation& Or) const;
+  void NextEdge();
+
+  //! Returns analyzed edge.
+  Standard_EXPORT void CurrentEdge(TopClass_GeomEdge& theGE) const;
+
+  //! Returns TRUE if thePnt is covered by the tolerance of at least one
+  //! vertex of the analyzed edge.
+  //! If it is true then stores the parameter of the vertex on the curve.
+  //! Otherwise, returns *theParameter = 0.0.
+  //! This parameter is used in TopOpeBRep class
+  //! and must be deleted after this class will be eliminated.
+  Standard_EXPORT Standard_Boolean IsPointInEdgeVertex(const gp_Pnt2d &thePnt,
+                                                       Standard_Real* const theParameter = 0) const;
+
+  //! Returns 1st considered ray
+  Standard_Boolean FirstRay(const gp_Pnt2d& theP,
+                            TopClass_RayInfo& theRay,
+                            const unsigned int theMaxRating = UINT_MAX)
+  {
+    // May return FALSE in case when the face is an infinite
+    // plane (see bugs modalg_6 bug25937* test cases)
+
+    ResetFields();
+
+    return OtherRay(theP, theRay, theMaxRating);
+  }
+
+  //! Clear private data
+  void ResetFields()
+  {
+    myCurEdgeInd = 1;
+    myCurEdgePar = myProbing_Start;
+  }
+
+  //! This method is used only for compatibility with TopOpeBRep
+  //! packages. It should be deleted after this package will be eliminated.
+  const TopoDS_Edge& GetTopoEdge() const
+  {
+    return myEExplorer.Value().GetTopoEdge();
+  }
+
+  //! Take UVBounds of the face. They are cached on first call.
+  Standard_EXPORT void UVBounds(Standard_Real& theUMin, Standard_Real& theUMax,
+                                Standard_Real& theVMin, Standard_Real& theVMax) const;
 
+protected:
 
+  //! Excludes all necessary information from theEdge
+  //! in order to create pseudo-edges in the future.
+  //! Returns FALSE if pseudo-edge creation is not necessary.
+  //! Returns 2D-point on the myFace (thePnt) respected to
+  //! theCurrentVertex.
+  //! Output parameter theOri indicates if theCurrentVertex
+  //! is first (FORWARD) or last (reversed) vertex of the theEdge.
+  //! ATTENTION!!! theCurrentVertex must be in theEdge.
+  Standard_EXPORT Standard_Boolean
+                    PrepareEdge(const TopoDS_Edge& theEdge,
+                                const TopoDS_Vertex& theCurrentVertex,
+                                gp_Pnt2d& thePnt,
+                                TopAbs_Orientation& theOri);
+
+  //! Inserts topological edge theEdge to myEList without
+  //! any additional checks.
+  Standard_EXPORT void SimpleAdd(const TopoDS_Edge &theEdge);
+
+  //! Creates pseudo-edge between and inserts it to myEList.
+  //! Pseudo-edge is 2D-line, which joins ends of theE1 and theE2
+  //! real edges. This edge does not have any 3D- and topological-
+  //! representations (pseudo-edge is not synonym of degenerated edge).
+  //! I.e. it is simple gap in the myFace. This gap must be covered
+  //! by theVertex (otherwise, myFace is not valid for using in OCCT-algorithms).
+  //! theUPeriod and theVPeriod are periods of myFace (are equal to 0.0 if
+  //! the surface is not periodic)
+  Standard_EXPORT void AddPseudo(const TopoDS_Edge& theE1,
+                                 const TopoDS_Edge& theE2,
+                                 const TopoDS_Vertex& theVertex,
+                                 const Standard_Real theUPeriod,
+                                 const Standard_Real theVPeriod);
 
+private:
 
-protected:
+  //! Classified face
+  TopoDS_Face myFace;
 
+  //! Surface got from the face (it includes location if any)
+  Handle(Geom_Surface) mySurf;
 
+  //! Flag defining whether UV bounds have been computed
+  mutable Standard_Boolean myBoundsComputed;
 
+  //! UV bounds of the face
+  mutable Standard_Real myUMin, myUMax, myVMin, myVMax;
 
+  //! Explores myFace to wires
+  NCollection_IndexedDataMap <TopoDS_Wire,
+                NCollection_List<TopClass_GeomEdge>> myMapWE;
 
-private:
+  //! Iterator of myMapWE
+  NCollection_IndexedDataMap <TopoDS_Wire,
+                      NCollection_List<TopClass_GeomEdge>>::Iterator myWExplorer;
 
+  //! Iterator of myEList
+  NCollection_List<TopClass_GeomEdge>::Iterator myEExplorer;
 
+  //! Ratio of the edge range to form ray
+  static const Standard_Real myProbing_Start, myProbing_End;
 
-  TopoDS_Face myFace;
-  TopExp_Explorer myWExplorer;
-  TopExp_Explorer myEExplorer;
+  //! Step for ratio
+  static const Standard_Real myProbing_Step;
+
+  //! The edge ID to form ray.
+  //! Ray joins the classified point
+  //! with some point of the edge.
   Standard_Integer myCurEdgeInd;
-  Standard_Real myCurEdgePar;
 
+  //! Parameter (on the edge) of the intersection point
+  //! between the ray and the edge
+  Standard_Real myCurEdgePar;
 
 };
 
-
 #include <BRepClass_FaceExplorer.lxx>
 
-
-
-
-
 #endif // _BRepClass_FaceExplorer_HeaderFile
diff --git a/src/BRepClass/BRepClass_FacePassiveClassifier.hxx b/src/BRepClass/BRepClass_FacePassiveClassifier.hxx
deleted file mode 100644
index 9063f70..0000000
--- a/src/BRepClass/BRepClass_FacePassiveClassifier.hxx
+++ /dev/null
@@ -1,127 +0,0 @@
-// Created on: 1992-11-18
-// Created by: Remi LEQUETTE
-// Copyright (c) 1992-1999 Matra Datavision
-// Copyright (c) 1999-2014 OPEN CASCADE SAS
-//
-// This file is part of Open CASCADE Technology software library.
-//
-// This library is free software; you can redistribute it and/or modify it under
-// the terms of the GNU Lesser General Public License version 2.1 as published
-// by the Free Software Foundation, with special exception defined in the file
-// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
-// distribution for complete text of the license and disclaimer of any warranty.
-//
-// Alternatively, this file may be used under the terms of Open CASCADE
-// commercial license or contractual agreement.
-
-#ifndef _BRepClass_FacePassiveClassifier_HeaderFile
-#define _BRepClass_FacePassiveClassifier_HeaderFile
-
-#include <Standard.hxx>
-#include <Standard_DefineAlloc.hxx>
-#include <Standard_Handle.hxx>
-
-#include <Standard_Boolean.hxx>
-#include <gp_Lin2d.hxx>
-#include <Standard_Real.hxx>
-#include <TopTrans_CurveTransition.hxx>
-#include <BRepClass_Intersector.hxx>
-#include <Standard_Integer.hxx>
-#include <TopAbs_State.hxx>
-#include <TopAbs_Orientation.hxx>
-class Standard_DomainError;
-class BRepClass_Edge;
-class BRepClass_Intersector;
-class gp_Lin2d;
-
-
-
-class BRepClass_FacePassiveClassifier 
-{
-public:
-
-  DEFINE_STANDARD_ALLOC
-
-  
-  //! Creates an undefined classifier.
-  Standard_EXPORT BRepClass_FacePassiveClassifier();
-  
-  //! Starts  a  classification process.   The  point to
-  //! classify is the origin of  the  line <L>.  <P>  is
-  //! the original length of the segment on <L>  used to
-  //! compute  intersections.   <Tol> is the   tolerance
-  //! attached to the line segment in intersections.
-  Standard_EXPORT void Reset (const gp_Lin2d& L, const Standard_Real P, const Standard_Real Tol);
-  
-  //! Updates  the classification process with  the edge
-  //! <E> from the boundary.
-  Standard_EXPORT void Compare (const BRepClass_Edge& E, const TopAbs_Orientation Or);
-  
-  //! Returns the current value of the parameter.
-    Standard_Real Parameter() const;
-  
-  //! Returns the intersecting algorithm.
-    BRepClass_Intersector& Intersector();
-  
-  //! Returns  0  if  the   last  compared   edge had no
-  //! relevant intersection.  Else returns  the index of
-  //! this   intersection  in the    last   intersection
-  //! algorithm.
-    Standard_Integer ClosestIntersection() const;
-  
-  //! Returns the current state of the point.
-    TopAbs_State State() const;
-  
-  //! Returns the Standard_True if the closest intersection point
-  //! represents head or end of the edge. Returns Standard_False
-  //! otherwise.
-    Standard_Boolean IsHeadOrEnd() const;
-
-
-
-
-protected:
-
-
-
-
-
-private:
-
-
-
-  Standard_Boolean myIsSet;
-  Standard_Boolean myFirstCompare;
-  Standard_Boolean myFirstTrans;
-  gp_Lin2d myLin;
-  Standard_Real myParam;
-  Standard_Real myTolerance;
-  TopTrans_CurveTransition myTrans;
-  BRepClass_Intersector myIntersector;
-  Standard_Integer myClosest;
-  TopAbs_State myState;
-  Standard_Boolean myIsHeadOrEnd;
-
-
-};
-
-#define TheEdge BRepClass_Edge
-#define TheEdge_hxx <BRepClass_Edge.hxx>
-#define TheIntersector BRepClass_Intersector
-#define TheIntersector_hxx <BRepClass_Intersector.hxx>
-#define TopClass_Classifier2d BRepClass_FacePassiveClassifier
-#define TopClass_Classifier2d_hxx <BRepClass_FacePassiveClassifier.hxx>
-
-#include <TopClass_Classifier2d.lxx>
-
-#undef TheEdge
-#undef TheEdge_hxx
-#undef TheIntersector
-#undef TheIntersector_hxx
-#undef TopClass_Classifier2d
-#undef TopClass_Classifier2d_hxx
-
-
-
-
-#endif // _BRepClass_FacePassiveClassifier_HeaderFile
diff --git a/src/BRepClass/BRepClass_FacePassiveClassifier_0.cxx b/src/BRepClass/BRepClass_FacePassiveClassifier_0.cxx
deleted file mode 100644
index 5e18e2b..0000000
--- a/src/BRepClass/BRepClass_FacePassiveClassifier_0.cxx
+++ /dev/null
@@ -1,32 +0,0 @@
-// Created on: 1992-11-18
-// Created by: Remi LEQUETTE
-// Copyright (c) 1992-1999 Matra Datavision
-// Copyright (c) 1999-2014 OPEN CASCADE SAS
-//
-// This file is part of Open CASCADE Technology software library.
-//
-// This library is free software; you can redistribute it and/or modify it under
-// the terms of the GNU Lesser General Public License version 2.1 as published
-// by the Free Software Foundation, with special exception defined in the file
-// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
-// distribution for complete text of the license and disclaimer of any warranty.
-//
-// Alternatively, this file may be used under the terms of Open CASCADE
-// commercial license or contractual agreement.
-
-#include <BRepClass_FacePassiveClassifier.hxx>
-
-#include <Standard_DomainError.hxx>
-#include <BRepClass_Edge.hxx>
-#include <BRepClass_Intersector.hxx>
-#include <gp_Lin2d.hxx>
- 
-
-#define TheEdge BRepClass_Edge
-#define TheEdge_hxx <BRepClass_Edge.hxx>
-#define TheIntersector BRepClass_Intersector
-#define TheIntersector_hxx <BRepClass_Intersector.hxx>
-#define TopClass_Classifier2d BRepClass_FacePassiveClassifier
-#define TopClass_Classifier2d_hxx <BRepClass_FacePassiveClassifier.hxx>
-#include <TopClass_Classifier2d.gxx>
-
diff --git a/src/BRepClass/BRepClass_Intersector.cxx b/src/BRepClass/BRepClass_Intersector.cxx
index 847d877..c5e5b9d 100644
--- a/src/BRepClass/BRepClass_Intersector.cxx
+++ b/src/BRepClass/BRepClass_Intersector.cxx
@@ -14,38 +14,19 @@
 // Alternatively, this file may be used under the terms of Open CASCADE
 // commercial license or contractual agreement.
 
-
-#include <BRep_Tool.hxx>
-#include <BRepAdaptor_Curve2d.hxx>
-#include <BRepAdaptor_Surface.hxx>
-#include <BRepClass_Edge.hxx>
 #include <BRepClass_Intersector.hxx>
+
+#include <Adaptor3d_HSurface.hxx>
 #include <ElCLib.hxx>
-#include <Extrema_ExtPC2d.hxx>
-#include <Geom2d_Curve.hxx>
 #include <Geom2d_Line.hxx>
 #include <Geom2dInt_GInter.hxx>
 #include <Geom2dLProp_CLProps2d.hxx>
-#include <gp_Dir2d.hxx>
-#include <gp_Lin2d.hxx>
-#include <IntRes2d_Domain.hxx>
-#include <IntRes2d_IntersectionPoint.hxx>
-#include <IntRes2d_Transition.hxx>
-#include <Precision.hxx>
-#include <TopExp.hxx>
-#include <TopoDS_Vertex.hxx>
-
-static 
-void RefineTolerance(const TopoDS_Face& aF,
-                     const BRepAdaptor_Curve2d& aC,
-                     const Standard_Real aT,
-                     Standard_Real& aTolZ);
+#include <TopClass_GeomEdge.hxx>
 
 //=======================================================================
 //function : BRepClass_Intersector
 //purpose  : 
 //=======================================================================
-
 BRepClass_Intersector::BRepClass_Intersector()
 {
 }
@@ -54,170 +35,51 @@ BRepClass_Intersector::BRepClass_Intersector()
 //function : Perform
 //purpose  : 
 //=======================================================================
-void  BRepClass_Intersector::Perform(const gp_Lin2d& L, 
-                                     const Standard_Real P, 
-                                     const Standard_Real Tol, 
-                                     const BRepClass_Edge& E)
+void  BRepClass_Intersector::Perform(const gp_Lin2d& theLin, 
+                                     const Standard_Real thePar,
+                                     const Standard_Real theTol2D,
+                                     const TopClass_GeomEdge& theGE)
 {
-  Standard_Real deb = 0.0, fin = 0.0, aTolZ = Tol;
-  Handle(Geom2d_Curve) aC2D;
-  //
-  const TopoDS_Edge& EE = E.Edge();
-  const TopoDS_Face& F = E.Face();
-
-  //
-  aC2D=BRep_Tool::CurveOnSurface(EE, F, deb, fin);
-  if (aC2D.IsNull()) {
+  if (theGE.IsNull())
+  {
     done = Standard_False; // !IsDone()
     return;
   }
-  //
-  BRepAdaptor_Curve2d C(EE, F);
-  //
-  deb = C.FirstParameter();
-  fin = C.LastParameter();
-  //
-  // Case of "ON": direct check of belonging to edge
-  // taking into account the tolerance
-  Extrema_ExtPC2d anExtPC2d(L.Location(), C);
-  Standard_Real MinDist = RealLast(), aDist;
-  Standard_Integer MinInd = 0, i;
-  if (anExtPC2d.IsDone())
-  {
-    const Standard_Integer aNbPnts = anExtPC2d.NbExt();
-    for (i = 1; i <= aNbPnts; ++i)
-    {
-      aDist = anExtPC2d.SquareDistance(i);
 
-      if (aDist < MinDist)
-      {
-        MinDist = aDist;
-        MinInd = i;
-      }
-    }
-  }
+  const gp_Pnt2d &aPnt2D = theLin.Location();
+  const Standard_Real aParF = theGE.FirstParameter();
+  const Standard_Real aParL = theGE.LastParameter();
+
+  const Geom2dAdaptor_Curve &anAdC2d = theGE.Get2DCurve();
 
-  if (MinInd) {
-    MinDist = sqrt(MinDist);
-  }
-  if (MinDist <= aTolZ) {
-    gp_Pnt2d pnt_exact = (anExtPC2d.Point(MinInd)).Value();
-    Standard_Real par = (anExtPC2d.Point(MinInd)).Parameter();
-    //
-    RefineTolerance(F, C, par, aTolZ);
-    //
-    if (MinDist <= aTolZ) {
-      IntRes2d_Transition tr_on_lin(IntRes2d_Head);
-      IntRes2d_Position pos_on_curve = IntRes2d_Middle;
-      if (Abs(par - deb) <= Precision::Confusion()) {
-        pos_on_curve = IntRes2d_Head;
-      }
-      else if (Abs(par - fin) <= Precision::Confusion()) {
-        pos_on_curve = IntRes2d_End;
-      }
-      //
-      IntRes2d_Transition tr_on_curve(pos_on_curve);
-      IntRes2d_IntersectionPoint pnt_inter(pnt_exact, 0., par,
-        tr_on_lin, tr_on_curve, 
-        Standard_False);
-      //
-      Append(pnt_inter);
-      done = Standard_True;
-      return;
-    }
-  }
   //  
   gp_Pnt2d pdeb,pfin;
-  C.D0(deb,pdeb);
-  C.D0(fin,pfin);
-  Standard_Real toldeb = 1.e-5, tolfin = 1.e-5;
+  anAdC2d.D0(aParF, pdeb);
+  anAdC2d.D0(aParL, pfin);
 
   IntRes2d_Domain DL;
-  //
-  if(P!=RealLast()) {
-    DL.SetValues(L.Location(),0.,Precision::PConfusion(),ElCLib::Value(P,L),P,Precision::PConfusion());
+  if (thePar != RealLast()) {
+    DL.SetValues(aPnt2D, 0., theTol2D, ElCLib::Value(thePar, theLin), thePar, theTol2D);
   }
   else { 
-    DL.SetValues(L.Location(),0.,Precision::PConfusion(),Standard_True);
+    DL.SetValues(aPnt2D, 0., theTol2D, Standard_True);
   }
 
-  IntRes2d_Domain DE(pdeb,deb,toldeb,pfin,fin,tolfin);
-  // temporary periodic domain
-  if (C.Curve()->IsPeriodic()) {
-    DE.SetEquivalentParameters(C.FirstParameter(),
-      C.FirstParameter() + 
-      C.Curve()->LastParameter() -
-      C.Curve()->FirstParameter());
-  }
+  IntRes2d_Domain DE(pdeb, aParF, Precision::PConfusion(), pfin, aParL, Precision::PConfusion());
+
+  // For the future.
+  // There is no point in intersecting geometrical curves. Here,
+  // intersection of line with polygonal-representation of the anAdC2d
+  // will be enough. After we determine the nearest (to the
+  // classified point) edge, only this edge needs to be GEOMETRICALY
+  // intersected with the line (e.g. in order to define correct transition).
+  // Currently, this algorithm is not implemented. Maybe it will be done in the future
+  // (in frame of performance improving)
 
-  Handle(Geom2d_Line) GL= new Geom2d_Line(L);
+  Handle(Geom2d_Line) GL = new Geom2d_Line(theLin);
   Geom2dAdaptor_Curve CGA(GL);
-  Geom2dInt_GInter Inter(CGA,DL,C,DE,
-    Precision::PConfusion(),
-    Precision::PIntersection());
+  Geom2dInt_GInter Inter(CGA, DL, anAdC2d, DE,
+                         Precision::PConfusion(), Precision::PIntersection());
   //
   SetValues(Inter);
-}
-
-//=======================================================================
-//function : LocalGeometry
-//purpose  : 
-//=======================================================================
-void  BRepClass_Intersector::LocalGeometry(const BRepClass_Edge& E, 
-                                           const Standard_Real U, 
-                                           gp_Dir2d& Tang, 
-                                           gp_Dir2d& Norm, 
-                                           Standard_Real& C) const 
-{
-  Standard_Real f,l;
-  Geom2dLProp_CLProps2d Prop(BRep_Tool::CurveOnSurface(E.Edge(),E.Face(),f,l),
-    U,2,Precision::PConfusion());
-  Prop.Tangent(Tang);
-  C = Prop.Curvature();
-  if (C > Precision::PConfusion())
-    Prop.Normal(Norm);
-  else
-    Norm.SetCoord(Tang.Y(),-Tang.X());
-}
-
-//=======================================================================
-//function : RefineTolerance
-//purpose  : 
-//=======================================================================
-void RefineTolerance(const TopoDS_Face& aF,
-                     const BRepAdaptor_Curve2d& aC,
-                     const Standard_Real aT,
-                     Standard_Real& aTolZ)
-{
-  GeomAbs_SurfaceType aTypeS;
-  //
-  BRepAdaptor_Surface aBAS(aF, Standard_False);
-  //
-  aTypeS=aBAS.GetType();
-  if (aTypeS==GeomAbs_Cylinder) {
-    Standard_Real aURes, aVRes, aTolX;
-    gp_Pnt2d aP2D;
-    gp_Vec2d aV2D;
-    //
-    aURes=aBAS.UResolution(aTolZ);
-    aVRes=aBAS.VResolution(aTolZ);
-    //
-    aC.D1(aT, aP2D, aV2D);
-    gp_Dir2d aD2D(aV2D);
-    //
-    aTolX=aURes*aD2D.Y()+aVRes*aD2D.X();
-    if (aTolX<0.) {
-      aTolX=-aTolX;
-    }
-    //
-    if (aTolX < Precision::Confusion()) {
-      aTolX = Precision::Confusion();
-    }
-    //
-    if (aTolX<aTolZ) {
-      aTolZ=aTolX;
-    }
-  }
-}
-
-
+}
\ No newline at end of file
diff --git a/src/BRepClass/BRepClass_Intersector.hxx b/src/BRepClass/BRepClass_Intersector.hxx
index e1b1742..2d79634 100644
--- a/src/BRepClass/BRepClass_Intersector.hxx
+++ b/src/BRepClass/BRepClass_Intersector.hxx
@@ -17,16 +17,10 @@
 #ifndef _BRepClass_Intersector_HeaderFile
 #define _BRepClass_Intersector_HeaderFile
 
-#include <Standard.hxx>
-#include <Standard_DefineAlloc.hxx>
-#include <Standard_Handle.hxx>
-
 #include <Geom2dInt_IntConicCurveOfGInter.hxx>
-#include <Standard_Real.hxx>
-class gp_Lin2d;
-class BRepClass_Edge;
-class gp_Dir2d;
 
+class Geom2dAdaptor_Curve;
+class TopClass_GeomEdge;
 
 //! Intersect an Edge  with a segment.
 //! Implement the Intersector2d required by the classifier.
@@ -40,34 +34,16 @@ public:
   Standard_EXPORT BRepClass_Intersector();
   
   //! Intersect the line segment and the edge.
-  Standard_EXPORT void Perform (const gp_Lin2d& L, const Standard_Real P, const Standard_Real Tol, const BRepClass_Edge& E);
-  
-  //! Returns in <T>,  <N> and <C>  the tangent,  normal
-  //! and  curvature of the edge  <E> at parameter value
-  //! <U>.
-  Standard_EXPORT void LocalGeometry (const BRepClass_Edge& E, const Standard_Real U, gp_Dir2d& T, gp_Dir2d& N, Standard_Real& C) const;
-
-
-
+  //! theTol2D is the 2D-intersection tolerance.
+  Standard_EXPORT void Perform(const gp_Lin2d& theLin,
+                               const Standard_Real thePar,
+                               const Standard_Real theTol2D,
+                               const TopClass_GeomEdge& theGE);
 
 protected:
 
-
-
-
-
 private:
 
-
-
-
-
 };
 
-
-
-
-
-
-
 #endif // _BRepClass_Intersector_HeaderFile
diff --git a/src/BRepClass/FILES b/src/BRepClass/FILES
index 3ead097..783c8ae 100644
--- a/src/BRepClass/FILES
+++ b/src/BRepClass/FILES
@@ -1,16 +1,11 @@
-BRepClass_Edge.cxx
-BRepClass_Edge.hxx
-BRepClass_Edge.lxx
+BRepClass_FClass2dOfFClassifier.hxx
+BRepClass_FClass2dOfFClassifier_0.cxx
+BRepClass_FClassifier.hxx
+BRepClass_FClassifier_0.cxx
 BRepClass_FaceClassifier.cxx
 BRepClass_FaceClassifier.hxx
 BRepClass_FaceExplorer.cxx
 BRepClass_FaceExplorer.hxx
 BRepClass_FaceExplorer.lxx
-BRepClass_FacePassiveClassifier.hxx
-BRepClass_FacePassiveClassifier_0.cxx
-BRepClass_FClass2dOfFClassifier.hxx
-BRepClass_FClass2dOfFClassifier_0.cxx
-BRepClass_FClassifier.hxx
-BRepClass_FClassifier_0.cxx
 BRepClass_Intersector.cxx
-BRepClass_Intersector.hxx
+BRepClass_Intersector.hxx
\ No newline at end of file
diff --git a/src/BRepClass3d/BRepClass3d_Intersector3d.cxx b/src/BRepClass3d/BRepClass3d_Intersector3d.cxx
index 1309b0b..a1da6cf 100644
--- a/src/BRepClass3d/BRepClass3d_Intersector3d.cxx
+++ b/src/BRepClass3d/BRepClass3d_Intersector3d.cxx
@@ -36,9 +36,9 @@ BRepClass3d_Intersector3d::BRepClass3d_Intersector3d()
 }
 //============================================================================
 void BRepClass3d_Intersector3d::Perform(const gp_Lin& L,
-					const Standard_Real /*Prm*/,
-					const Standard_Real Tol,
-					const TopoDS_Face& Face) { 
+                                        const Standard_Real theTol3D,
+                                        const TopoDS_Face& Face)
+{
 
   IntCurveSurface_HInter   HICS; 
   BRepAdaptor_Surface      surface;
@@ -96,15 +96,16 @@ void BRepClass3d_Intersector3d::Perform(const gp_Lin& L,
         Puv.SetY(Y - vperiod * N2);
       }
 
-      classifier2d.Perform(Face,Puv,Tol);
+      classifier2d.Perform(Face, Puv, theTol3D);
       TopAbs_State currentstate = classifier2d.State();
       if(currentstate==TopAbs_IN || currentstate==TopAbs_ON) { 
-	const IntCurveSurface_IntersectionPoint& HICSPoint = HICS.Point(index);
-	Standard_Real HICSW = HICSPoint.W();
-//  Modified by skv - Fri Mar  4 12:07:34 2005 OCC7966 Begin
-	if((W > HICSW) && (HICSW>-Tol)) { 
-// 	if(W > HICSW) { 
-//  Modified by skv - Fri Mar  4 12:07:34 2005 OCC7966 End
+        const IntCurveSurface_IntersectionPoint& HICSPoint = HICS.Point(index);
+        Standard_Real HICSW = HICSPoint.W();
+        
+        // Must be "HICSW > -<Curve Resolution>(theTol3D)" but
+        // the curve is Geom_Line. Therefore, its resolution is equal to theTol3D.
+        if((W > HICSW) && (HICSW>-theTol3D))
+        { 
 	  hasapoint  = Standard_True;
 	  U          = HICSPoint.U();
 	  V          = HICSPoint.V();
diff --git a/src/BRepClass3d/BRepClass3d_Intersector3d.hxx b/src/BRepClass3d/BRepClass3d_Intersector3d.hxx
index 4c6d776..ccb759f 100644
--- a/src/BRepClass3d/BRepClass3d_Intersector3d.hxx
+++ b/src/BRepClass3d/BRepClass3d_Intersector3d.hxx
@@ -43,17 +43,19 @@ public:
   //! Empty constructor.
   Standard_EXPORT BRepClass3d_Intersector3d();
   
-  //! Perform the intersection between the
-  //! segment L(0) ... L(Prm) and the Shape <Sh>.
+  //! Perform the intersection between theL
+  //! and the face <theF>.
   //!
   //! Only the point with the smallest parameter on the
   //! line is returned.
   //!
-  //! The Tolerance <Tol> is used to determine if the
-  //! first point of the segment is near the face. In
+  //! The Tolerance <theTol3D> is used to determine if the
+  //! first point of the segment is near to the face. In
   //! that case, the parameter of the intersection point
-  //! on the line can be a negative value (greater than -Tol).
-  Standard_EXPORT void Perform (const gp_Lin& L, const Standard_Real Prm, const Standard_Real Tol, const TopoDS_Face& F);
+  //! on the line can be equal to a negative value (greater than -Tol).
+  Standard_EXPORT void Perform(const gp_Lin& theL, 
+                               const Standard_Real theTol3D,
+                               const TopoDS_Face& theF);
   
   //! True is returned when the intersection have been computed.
     Standard_Boolean IsDone() const;
diff --git a/src/BRepClass3d/BRepClass3d_SolidExplorer.cxx b/src/BRepClass3d/BRepClass3d_SolidExplorer.cxx
index ae47f52..91246b2 100644
--- a/src/BRepClass3d/BRepClass3d_SolidExplorer.cxx
+++ b/src/BRepClass3d/BRepClass3d_SolidExplorer.cxx
@@ -33,9 +33,8 @@
 #include <BRepBndLib.hxx>
 #include <BRepClass3d_DataMapIteratorOfMapOfInter.hxx>
 #include <BRepClass3d_SolidExplorer.hxx>
-#include <BRepClass_Edge.hxx>
 #include <BRepClass_FaceClassifier.hxx>
-#include <BRepClass_FacePassiveClassifier.hxx>
+#include <BRepClass_FClass2dOfFClassifier.hxx>
 #include <BRepTools.hxx>
 #include <BRepTopAdaptor_FClass2d.hxx>
 #include <ElCLib.hxx>
@@ -134,14 +133,15 @@ Standard_Boolean BRepClass3d_SolidExplorer::FindAPointInTheFace
     Standard_Real TolInit   = 0.00001;
     Standard_Boolean APointExist = Standard_False;
 
-    BRepClass_FacePassiveClassifier FClassifier;
+    BRepClass_FClass2dOfFClassifier FClassifier;
 
     T.Normalize();
     P.SetCoord (P.X() + TolInit * T.X(), P.Y() + TolInit * T.Y());
-    FClassifier.Reset (gp_Lin2d (P, T), ParamInit, RealEpsilon()); //-- Length and Tolerance #######
+    FClassifier.Reset (gp_Lin2d (P, T), ParamInit); //-- Length and Tolerance #######
 
     TopExp_Explorer otherfaceexplorer;
     Standard_Integer aNbEdges = 0;
+    const Handle(Geom_Surface) aSurf = BRep_Tool::Surface(face);
     for (otherfaceexplorer.Init (face, TopAbs_EDGE);
          otherfaceexplorer.More(); 
          otherfaceexplorer.Next(), ++aNbEdges)
@@ -149,8 +149,10 @@ Standard_Boolean BRepClass3d_SolidExplorer::FindAPointInTheFace
       TopoDS_Edge OtherEdge = TopoDS::Edge (otherfaceexplorer.Current());
       if (OtherEdge.Orientation() != TopAbs_EXTERNAL && OtherEdge != Edge)
       {
-        BRepClass_Edge AEdge (OtherEdge, face);
-        FClassifier.Compare (AEdge, OtherEdge.Orientation());
+        Standard_Real aFPar, aLPar;
+        const Handle(Geom2d_Curve) aC2d = BRep_Tool::CurveOnSurface(OtherEdge, face, aFPar, aLPar);
+        TopClass_GeomEdge AEdge(OtherEdge, aSurf, aC2d, aFPar, aLPar);
+        FClassifier.Compare(AEdge, Precision::PConfusion());
         if (FClassifier.ClosestIntersection())
         {
           if(ParamInit > FClassifier.Parameter())
@@ -164,8 +166,10 @@ Standard_Boolean BRepClass3d_SolidExplorer::FindAPointInTheFace
 
     if (aNbEdges == 1)
     {
-      BRepClass_Edge AEdge (Edge, face);
-      FClassifier.Compare (AEdge, Edge.Orientation());
+      Standard_Real aFPar, aLPar;
+      const Handle(Geom2d_Curve) aC2d = BRep_Tool::CurveOnSurface(Edge, face, aFPar, aLPar);
+      TopClass_GeomEdge AEdge(Edge, aSurf, aC2d, aFPar, aLPar);
+      FClassifier.Compare(AEdge, Precision::PConfusion());
       if (FClassifier.ClosestIntersection())
       {
         if (ParamInit > FClassifier.Parameter())
@@ -561,7 +565,7 @@ Standard_Integer BRepClass3d_SolidExplorer::OtherSegment(const gp_Pnt& P,
 
             gp_Pnt2d aPuv(aU, aV);
 
-            classifier2d.Perform(face,aPuv,Precision::PConfusion());
+            classifier2d.Perform(face,aPuv,Precision::Confusion());
 
             TopAbs_State aState = classifier2d.State();
 
diff --git a/src/BRepExtrema/BRepExtrema_DistanceSS.cxx b/src/BRepExtrema/BRepExtrema_DistanceSS.cxx
index 61773dd..877f91d 100644
--- a/src/BRepExtrema/BRepExtrema_DistanceSS.cxx
+++ b/src/BRepExtrema/BRepExtrema_DistanceSS.cxx
@@ -442,7 +442,6 @@ static void PERFORM_C0(const TopoDS_Edge &S1, const TopoDS_Edge &S2,
 
       gp_Pnt P1,Pt;
       Standard_Integer i, ii;  
-      BRepClass_FaceClassifier classifier;
       for (i = 1; i <= arrInter.Length(); i++)
       {
         const Standard_Real aParameter = arrInter(i);
@@ -791,7 +790,8 @@ void BRepExtrema_DistanceSS::Perform(const TopoDS_Vertex& S1, const TopoDS_Face&
         Standard_Real U,V;
         gp_Pnt Pt,P1=BRep_Tool::Pnt(S1);
         BRepClass_FaceClassifier classifier;
-        const Standard_Real tol = BRep_Tool::Tolerance(S2);
+        BRepAdaptor_Surface anAS(S2, Standard_False);
+        const Standard_Real aTol = BRep_Tool::Tolerance(S2);
  
         for (i = 1; i <= NbExtrema; i++)
         {
@@ -803,7 +803,7 @@ void BRepExtrema_DistanceSS::Perform(const TopoDS_Vertex& S1, const TopoDS_Face&
               // Check if the parameter does not correspond to a vertex
               Ext.Parameter(i,U,V);
               const gp_Pnt2d PUV(U,V);
-              classifier.Perform(S2,PUV,tol);
+              classifier.Perform(S2, PUV, aTol);
               if (classifier.State()==TopAbs_IN)
               {
                 if (myDstRef > Dstmin)
@@ -847,7 +847,7 @@ void BRepExtrema_DistanceSS::Perform(const TopoDS_Face& S1, const TopoDS_Vertex&
         Standard_Real U,V;
         gp_Pnt Pt,P2=BRep_Tool::Pnt(S2);
         BRepClass_FaceClassifier classifier;
-        const Standard_Real tol = BRep_Tool::Tolerance(S1);
+        const Standard_Real aTol = BRep_Tool::Tolerance(S1);
  
         for (i = 1; i <= NbExtrema; i++)
         {
@@ -859,7 +859,7 @@ void BRepExtrema_DistanceSS::Perform(const TopoDS_Face& S1, const TopoDS_Vertex&
               // Check if the parameter does not correspond to a vertex
               Ext.Parameter(i,U,V);
               const gp_Pnt2d PUV(U,V);
-              classifier.Perform(S1,PUV,tol);
+              classifier.Perform(S1, PUV, aTol);
               if (classifier.State()==TopAbs_IN)
               {
                 if (myDstRef > Dstmin)
@@ -992,8 +992,7 @@ void BRepExtrema_DistanceSS::Perform(const TopoDS_Edge& S1, const TopoDS_Face& S
       {
         Standard_Real Udeb,Ufin,U,V;
         BRep_Tool::Range(S1,Udeb,Ufin);
-        const Standard_Real tol=BRep_Tool::Tolerance(S2);
-
+        const Standard_Real aTol = BRep_Tool::Tolerance(S2);
         gp_Pnt Pt1,Pt2;
         const Standard_Real epsP=Precision::PConfusion();
 
@@ -1011,7 +1010,7 @@ void BRepExtrema_DistanceSS::Perform(const TopoDS_Edge& S1, const TopoDS_Face& S
               {
                 Ext.ParameterOnFace(i,U,V);
                 const gp_Pnt2d PUV(U,V);
-                classifier.Perform(S2,PUV,tol);
+                classifier.Perform(S2, PUV, aTol);
                 if (classifier.State()==TopAbs_IN)
                 {
                   if (myDstRef > Dstmin)
@@ -1044,8 +1043,7 @@ void BRepExtrema_DistanceSS::Perform(const TopoDS_Edge& S1, const TopoDS_Face& S
 
       gp_Pnt Pt;
       Standard_Real U,V;
-      const Standard_Real tol = BRep_Tool::Tolerance(S2);
-
+      const Standard_Real aTol = BRep_Tool::Tolerance(S2);
       Standard_Integer i;
       for (i = 1; i <= arrInter.Length(); i++)
       {
@@ -1077,7 +1075,7 @@ void BRepExtrema_DistanceSS::Perform(const TopoDS_Edge& S1, const TopoDS_Face& S
                 // Check if the parameter does not correspond to a vertex
                 ExtPF.Parameter(ii,U,V);
                 const gp_Pnt2d PUV(U,V);
-				classifier.Perform(S2,PUV,tol);
+                classifier.Perform(S2, PUV, aTol);
                 if (classifier.State()==TopAbs_IN)
                 {
                   if (myDstRef > Dstmin)
@@ -1137,8 +1135,7 @@ void BRepExtrema_DistanceSS::Perform(const TopoDS_Face& S1, const TopoDS_Edge& S
       {
         Standard_Real Udeb,Ufin,U,V;
         BRep_Tool::Range(S2,Udeb,Ufin);
-        const Standard_Real tol=BRep_Tool::Tolerance(S1);
-
+        const Standard_Real aTol = BRep_Tool::Tolerance(S1);
         gp_Pnt Pt1,Pt2;
         const Standard_Real epsP=Precision::PConfusion();
 
@@ -1156,7 +1153,7 @@ void BRepExtrema_DistanceSS::Perform(const TopoDS_Face& S1, const TopoDS_Edge& S
               {
                 Ext.ParameterOnFace(i,U,V);
                 const gp_Pnt2d PUV(U,V);
-                classifier.Perform(S1,PUV,tol);
+                classifier.Perform(S1, PUV, aTol);
                 if (classifier.State()==TopAbs_IN)
                 {
                   if (myDstRef > Dstmin)
@@ -1189,8 +1186,7 @@ void BRepExtrema_DistanceSS::Perform(const TopoDS_Face& S1, const TopoDS_Edge& S
 
       gp_Pnt Pt;
       Standard_Real U,V;
-      const Standard_Real tol = BRep_Tool::Tolerance(S1);
-
+      const Standard_Real aTol = BRep_Tool::Tolerance(S1);
       Standard_Integer i;
       for (i = 1; i <= arrInter.Length(); i++)
       {
@@ -1222,7 +1218,7 @@ void BRepExtrema_DistanceSS::Perform(const TopoDS_Face& S1, const TopoDS_Edge& S
                 // Check if the parameter does not correspond to a vertex
                 ExtPF.Parameter(ii,U,V);
                 const gp_Pnt2d PUV(U,V);
-				classifier.Perform(S1,PUV,tol);
+                classifier.Perform(S1, PUV, aTol);
                 if (classifier.State()==TopAbs_IN)
                 {
                   if (myDstRef > Dstmin)
@@ -1277,8 +1273,8 @@ void BRepExtrema_DistanceSS::Perform(const TopoDS_Face& S1, const TopoDS_Face& S
       Dstmin = sqrt(Dstmin);
       if ((Dstmin < myDstRef - myEps) || (fabs(Dstmin-myDstRef) < myEps))
       {
-        const Standard_Real tol1=BRep_Tool::Tolerance(S1);
-        const Standard_Real tol2=BRep_Tool::Tolerance(S2);
+        const Standard_Real aTol1=BRep_Tool::Tolerance(S1);
+        const Standard_Real aTol2=BRep_Tool::Tolerance(S2);
 
         gp_Pnt Pt1,Pt2;
         gp_Pnt2d PUV;
@@ -1296,12 +1292,12 @@ void BRepExtrema_DistanceSS::Perform(const TopoDS_Face& S1, const TopoDS_Face& S
               // Check if the parameter does not correspond to a vertex
               Ext.ParameterOnFace1(i,U1,V1);
               PUV.SetCoord(U1,V1);
-              classifier.Perform(S1,PUV,tol1);
+              classifier.Perform(S1, PUV, aTol1);
               if (classifier.State()==TopAbs_IN)
               {
                 Ext.ParameterOnFace2(i,U2,V2);
                 PUV.SetCoord(U2,V2);
-                classifier.Perform(S2,PUV,tol2);
+                classifier.Perform(S2, PUV, aTol2);
                 if (classifier.State()==TopAbs_IN)
                 {
                   if (myDstRef > Dstmin)
diff --git a/src/BRepExtrema/BRepExtrema_ExtCF.cxx b/src/BRepExtrema/BRepExtrema_ExtCF.cxx
index 59d67b3..22fecc8 100644
--- a/src/BRepExtrema/BRepExtrema_ExtCF.cxx
+++ b/src/BRepExtrema/BRepExtrema_ExtCF.cxx
@@ -95,7 +95,7 @@ void BRepExtrema_ExtCF::Perform(const TopoDS_Edge& E, const TopoDS_Face& F2)
   {
     // Exploration of points and classification
     BRepClass_FaceClassifier classifier;
-    const Standard_Real Tol = BRep_Tool::Tolerance(F2);
+    const Standard_Real aTol = BRep_Tool::Tolerance(F2);
     Extrema_POnCurv P1;
     Extrema_POnSurf P2;
 
@@ -104,7 +104,7 @@ void BRepExtrema_ExtCF::Perform(const TopoDS_Edge& E, const TopoDS_Face& F2)
       myExtCS.Points(i, P1, P2);
       P2.Parameter(U1, U2);
       const gp_Pnt2d Puv(U1, U2);
-      classifier.Perform(F2, Puv, Tol);
+      classifier.Perform(F2, Puv, aTol);
       const TopAbs_State state = classifier.State();
       if (state == TopAbs_ON || state == TopAbs_IN)
       {
diff --git a/src/BRepExtrema/BRepExtrema_ExtFF.cxx b/src/BRepExtrema/BRepExtrema_ExtFF.cxx
index e777f25..252f744 100644
--- a/src/BRepExtrema/BRepExtrema_ExtFF.cxx
+++ b/src/BRepExtrema/BRepExtrema_ExtFF.cxx
@@ -69,17 +69,20 @@ void BRepExtrema_ExtFF::Perform(const TopoDS_Face& F1, const TopoDS_Face& F2)
   myPointsOnS1.Clear();
   myPointsOnS2.Clear();
 
-  BRepAdaptor_Surface Surf1(F1);
-  if (myHS.IsNull() || Surf1.GetType() == GeomAbs_OtherSurface)
+  BRepAdaptor_Surface Surf1(F1, Standard_False), Surf2(F2, Standard_False);
+  if (myHS.IsNull() ||
+     (Surf1.GetType() == GeomAbs_OtherSurface) ||
+     (Surf2.GetType() == GeomAbs_OtherSurface))
     return; // protect against non-geometric type (e.g. triangulation)
 
   Handle(BRepAdaptor_HSurface) HS1 = new BRepAdaptor_HSurface(Surf1);
-  Standard_Real Tol1 = Min(BRep_Tool::Tolerance(F1), Precision::Confusion());
-  Tol1 = Min(Surf1.UResolution(Tol1), Surf1.VResolution(Tol1));
-  Tol1 = Max(Tol1, Precision::PConfusion());
+  const Standard_Real aTol1 = BRep_Tool::Tolerance(F1),
+                      aTol2 = BRep_Tool::Tolerance(F2);
   Standard_Real U1, U2, V1, V2;
   BRepTools::UVBounds(F1, U1, U2, V1, V2);
-  myExtSS.Perform(HS1->Surface(), U1, U2, V1, V2, Tol1);
+  myExtSS.Perform(HS1->Surface(), U1, U2, V1, V2, Max(Min(Surf1.UResolution(aTol1),
+                                                          Surf1.VResolution(aTol1)),
+                                                            Precision::PConfusion()));
 
   if (!myExtSS.IsDone())
     return;
@@ -90,7 +93,6 @@ void BRepExtrema_ExtFF::Perform(const TopoDS_Face& F1, const TopoDS_Face& F2)
   {
     // Exploration of points and classification
     BRepClass_FaceClassifier classifier;
-    const Standard_Real Tol2 = BRep_Tool::Tolerance(F2);
     Extrema_POnSurf P1, P2;
 
     Standard_Integer i;
@@ -99,13 +101,13 @@ void BRepExtrema_ExtFF::Perform(const TopoDS_Face& F1, const TopoDS_Face& F2)
       myExtSS.Points(i, P1, P2);
       P1.Parameter(U1, U2);
       const gp_Pnt2d Puv1(U1, U2);
-      classifier.Perform(F1, Puv1, Tol1);
+      classifier.Perform(F1, Puv1, aTol1);
       const TopAbs_State state1 = classifier.State();
       if (state1 == TopAbs_ON || state1 == TopAbs_IN)
       {
         P2.Parameter(U1, U2);
         const gp_Pnt2d Puv2(U1, U2);
-        classifier.Perform(F2, Puv2, Tol2);
+        classifier.Perform(F2, Puv2, aTol2);
         const TopAbs_State state2 = classifier.State();
         if (state2 == TopAbs_ON || state2 == TopAbs_IN)
         {
diff --git a/src/BRepExtrema/BRepExtrema_ExtPF.cxx b/src/BRepExtrema/BRepExtrema_ExtPF.cxx
index 4149390..de93cb0 100644
--- a/src/BRepExtrema/BRepExtrema_ExtPF.cxx
+++ b/src/BRepExtrema/BRepExtrema_ExtPF.cxx
@@ -85,12 +85,13 @@ void BRepExtrema_ExtPF::Perform(const TopoDS_Vertex& TheVertex, const TopoDS_Fac
   {
     BRepClass_FaceClassifier classifier;
     Standard_Real U1, U2;
-    const Standard_Real Tol = BRep_Tool::Tolerance(TheFace);
+    BRepAdaptor_Surface anAS(TheFace, Standard_False);
+    const Standard_Real aTol = BRep_Tool::Tolerance(TheFace);
     for (Standard_Integer i = 1; i <= myExtPS.NbExt(); i++)
     {
       myExtPS.Point(i).Parameter(U1, U2);
       const gp_Pnt2d Puv(U1, U2);
-      classifier.Perform(TheFace, Puv, Tol);
+      classifier.Perform(TheFace, Puv, aTol);
       const TopAbs_State state = classifier.State();
       if(state == TopAbs_ON || state == TopAbs_IN)
       {
diff --git a/src/BRepFeat/BRepFeat_RibSlot.cxx b/src/BRepFeat/BRepFeat_RibSlot.cxx
index 0ac9d16..7172bef 100644
--- a/src/BRepFeat/BRepFeat_RibSlot.cxx
+++ b/src/BRepFeat/BRepFeat_RibSlot.cxx
@@ -1518,7 +1518,9 @@ Standard_Boolean BRepFeat_RibSlot::SlidingProfile(TopoDS_Face& Prof,
 // if not concave
 // CheckPnt : point slightly inside the material side
 // Bndface  : face/cut of the bounding box in the plane of the profile
-    BRepTopAdaptor_FClass2d Cl(fac, BRep_Tool::Tolerance(fac));
+    
+    const Standard_Real aTolF = BRep_Tool::Tolerance(fac);
+    BRepTopAdaptor_FClass2d Cl(fac, aTolF);
     Standard_Real u, v;
     ElSLib::Parameters(myPln->Pln(), CheckPnt, u, v);
     gp_Pnt2d checkpnt2d(u, v);
@@ -2205,7 +2207,8 @@ Standard_Boolean BRepFeat_RibSlot::NoSlidingProfile(TopoDS_Face& Prof,
   
 //    if(!Concavite) {
   if(Concavite == 3) {
-    BRepTopAdaptor_FClass2d Cl(fac, BRep_Tool::Tolerance(fac));
+    const Standard_Real aTolF = BRep_Tool::Tolerance(fac);
+    BRepTopAdaptor_FClass2d Cl(fac, aTolF);
     Standard_Real u, v;
     ElSLib::Parameters(myPln->Pln(), CheckPnt, u, v);
     gp_Pnt2d checkpnt2d(u, v);
diff --git a/src/BRepIntCurveSurface/BRepIntCurveSurface_Inter.cxx b/src/BRepIntCurveSurface/BRepIntCurveSurface_Inter.cxx
index 0bf8e39..50b4852 100644
--- a/src/BRepIntCurveSurface/BRepIntCurveSurface_Inter.cxx
+++ b/src/BRepIntCurveSurface/BRepIntCurveSurface_Inter.cxx
@@ -95,12 +95,13 @@ void BRepIntCurveSurface_Inter::Clear()
 //purpose  : 
 //===========================================================================
 
-void BRepIntCurveSurface_Inter::Load(const TopoDS_Shape& theShape ,const Standard_Real theTol)
+void BRepIntCurveSurface_Inter::Load(const TopoDS_Shape& theShape,
+                                     const Standard_Real theTol3D)
 {
   Clear();
   myFaces.Clear();
   myFaceBoxes.Nullify();
-  myTolerance = theTol;
+  my3DTolerance = theTol3D;
   TopExp_Explorer explorer(theShape,TopAbs_FACE);
   for( ; explorer.More(); explorer.Next())
     myFaces.Append(explorer.Current());
@@ -166,7 +167,7 @@ void BRepIntCurveSurface_Inter::Find()
     if( aFaceBox.IsVoid())
     {
       BRepBndLib::Add(aCurface, aFaceBox);
-      aFaceBox.SetGap(myTolerance);//Precision::Confusion());
+      aFaceBox.SetGap(my3DTolerance);//Precision::Confusion());
     }
     Standard_Boolean isOut = ( myCurve->GetType() == GeomAbs_Line ? aFaceBox.IsOut(myCurve->Line()) :
       ( !myCurveBox.IsVoid() ? aFaceBox.IsOut(myCurveBox ) : Standard_False ) );
@@ -200,7 +201,6 @@ void BRepIntCurveSurface_Inter::Find()
 Standard_Boolean BRepIntCurveSurface_Inter::FindPoint()
 {
   Standard_Integer j =  (!myCurrentindex ?  1 : myCurrentindex);
-  
   for( ; j <= myCurrentnbpoints; j++ )
   {
     Standard_Real anU = myIntcs.Point(j).U();
@@ -208,7 +208,7 @@ Standard_Boolean BRepIntCurveSurface_Inter::FindPoint()
   
     gp_Pnt2d Puv( anU,aV );
 
-    myCurrentstate = myFastClass->Classify(Puv,myTolerance); 
+    myCurrentstate = myFastClass->Classify(Puv, my3DTolerance);
     if(myCurrentstate == TopAbs_ON || myCurrentstate == TopAbs_IN) 
     { 
       myCurrentindex = j;
diff --git a/src/BRepIntCurveSurface/BRepIntCurveSurface_Inter.hxx b/src/BRepIntCurveSurface/BRepIntCurveSurface_Inter.hxx
index eaf62be..da25508 100644
--- a/src/BRepIntCurveSurface/BRepIntCurveSurface_Inter.hxx
+++ b/src/BRepIntCurveSurface/BRepIntCurveSurface_Inter.hxx
@@ -128,7 +128,7 @@ protected:
   //! Internal function
   Standard_EXPORT void Find();
   
-  //! Method chec found intersection point
+  //! Method check found intersection point
   Standard_EXPORT Standard_Boolean FindPoint();
   
   //! Method to clear fields of class
@@ -141,7 +141,7 @@ private:
 
 
 
-  Standard_Real myTolerance;
+  Standard_Real my3DTolerance;
   Handle(GeomAdaptor_HCurve) myCurve;
   IntCurveSurface_HInter myIntcs;
   Standard_Integer myCurrentindex;
diff --git a/src/BRepLib/BRepLib_FindSurface.cxx b/src/BRepLib/BRepLib_FindSurface.cxx
index 998176d..965d008 100644
--- a/src/BRepLib/BRepLib_FindSurface.cxx
+++ b/src/BRepLib/BRepLib_FindSurface.cxx
@@ -565,7 +565,7 @@ void BRepLib_FindSurface::Init(const TopoDS_Shape&    S,
       TopoDS_Face aTmpFace = BRepLib_MakeFace(mySurface, Precision::Confusion());
       BRep_Builder BB;
       BB.Add(aTmpFace, aW);
-      BRepTopAdaptor_FClass2d FClass(aTmpFace, 0.);
+      BRepTopAdaptor_FClass2d FClass(aTmpFace, gp::Resolution());
       if ( FClass.PerformInfinitePoint() == TopAbs_IN ) 
       {
         gp_Dir aN = aPlane->Position().Direction();
diff --git a/src/BRepLib/BRepLib_MakeFace.cxx b/src/BRepLib/BRepLib_MakeFace.cxx
index 8046062..90336af 100644
--- a/src/BRepLib/BRepLib_MakeFace.cxx
+++ b/src/BRepLib/BRepLib_MakeFace.cxx
@@ -849,7 +849,7 @@ void BRepLib_MakeFace::CheckInside()
 {
   // compute the area and return the face if the area is negative
   TopoDS_Face F = TopoDS::Face(myShape);
-  BRepTopAdaptor_FClass2d FClass(F,0.);
+  BRepTopAdaptor_FClass2d FClass(F,gp::Resolution());
   if ( FClass.PerformInfinitePoint() == TopAbs_IN) {
     BRep_Builder B;
     TopoDS_Shape S = myShape.EmptyCopied();
diff --git a/src/BRepMesh/BRepMesh_Classifier.cxx b/src/BRepMesh/BRepMesh_Classifier.cxx
index 09545b4..228e602 100644
--- a/src/BRepMesh/BRepMesh_Classifier.cxx
+++ b/src/BRepMesh/BRepMesh_Classifier.cxx
@@ -40,7 +40,7 @@ TopAbs_State BRepMesh_Classifier::Perform(const gp_Pnt2d& thePoint) const
   
   for (Standard_Integer i = 1; i <= aNb; i++)
   {
-    Standard_Integer aCur = ((CSLib_Class2d*)myTabClass(i))->SiDans(thePoint);
+    Standard_Integer aCur = ((CSLib_Class2d*)myTabClass(i))->Classify(thePoint);
     if (aCur == 0)
     {
       // Point is ON, but mark it as OUT
diff --git a/src/BRepOffset/BRepOffset_MakeOffset.cxx b/src/BRepOffset/BRepOffset_MakeOffset.cxx
index e9e565d..b227376 100644
--- a/src/BRepOffset/BRepOffset_MakeOffset.cxx
+++ b/src/BRepOffset/BRepOffset_MakeOffset.cxx
@@ -28,6 +28,7 @@
 #include <BRepAdaptor_Curve.hxx>
 #include <BRepAdaptor_Curve2d.hxx>
 #include <BRepAdaptor_Surface.hxx>
+#include <BRepTopAdaptor_FClass2d.hxx>
 #include <BRepAlgo_AsDes.hxx>
 #include <BRepAlgo_Image.hxx>
 #include <BRepCheck_Analyzer.hxx>
@@ -81,7 +82,6 @@
 #include <gp_Lin2d.hxx>
 #include <gp_Pnt.hxx>
 #include <GProp_GProps.hxx>
-#include <IntTools_FClass2d.hxx>
 #include <NCollection_List.hxx>
 #include <Precision.hxx>
 #include <Standard_ConstructionError.hxx>
@@ -2669,7 +2669,7 @@ void BRepOffset_MakeOffset::MakeMissingWalls ()
               TopoDS_Edge aE1, aE2;
               TopoDS_Wire aW1, aW2;
               Handle(Geom_Plane) aPL;
-              IntTools_FClass2d aClsf;
+              BRepTopAdaptor_FClass2d aClsf;
               //
               if (aCirc.Radius()>aCircOE.Radius()) {
                 aE1 = anEdge;
diff --git a/src/BRepOffset/BRepOffset_Tool.cxx b/src/BRepOffset/BRepOffset_Tool.cxx
index e8965ec..1f89c10 100644
--- a/src/BRepOffset/BRepOffset_Tool.cxx
+++ b/src/BRepOffset/BRepOffset_Tool.cxx
@@ -3856,11 +3856,9 @@ void BRepOffset_Tool::CorrectOrientation(const TopoDS_Shape&        SI,
 	if (NewEdges.Contains(OE)) {YaInt = Standard_True; break;}
       }
       if (YaInt) {
-	TopoDS_Shape aLocalFace = FI.Oriented(TopAbs_FORWARD);
-	BRepTopAdaptor_FClass2d FC (TopoDS::Face(aLocalFace),
-				    Precision::Confusion());
-//	BRepTopAdaptor_FClass2d FC (TopoDS::Face(FI.Oriented(TopAbs_FORWARD)),
-//				    Precision::Confusion());
+        TopoDS_Shape aLocalFace = FI.Oriented(TopAbs_FORWARD);
+        BRepTopAdaptor_FClass2d FC (TopoDS::Face(aLocalFace),
+                                    Precision::Confusion());
 	for (itE.Initialize(LOE); itE.More(); itE.Next()) {
 	  TopoDS_Shape&   OE   = itE.Value();
 	  if (NewEdges.Contains(OE)) {
diff --git a/src/BRepTopAdaptor/BRepTopAdaptor_FClass2d.cxx b/src/BRepTopAdaptor/BRepTopAdaptor_FClass2d.cxx
index 1ab9716e..decc3b4 100644
--- a/src/BRepTopAdaptor/BRepTopAdaptor_FClass2d.cxx
+++ b/src/BRepTopAdaptor/BRepTopAdaptor_FClass2d.cxx
@@ -14,10 +14,7 @@
 // Alternatively, this file may be used under the terms of Open CASCADE
 // commercial license or contractual agreement.
 
-#define AFFICHAGE 0
-
-#define No_Standard_OutOfRange
-
+#include <BRepTopAdaptor_FClass2d.hxx>
 
 #include <BRep_Tool.hxx>
 #include <BRepAdaptor_Curve.hxx>
@@ -25,743 +22,1090 @@
 #include <BRepAdaptor_HSurface.hxx>
 #include <BRepClass_FaceClassifier.hxx>
 #include <BRepTools_WireExplorer.hxx>
-#include <BRepTopAdaptor_FClass2d.hxx>
 #include <CSLib_Class2d.hxx>
 #include <ElCLib.hxx>
-#include <Geom2dInt_Geom2dCurveTool.hxx>
-#include <GeomAbs_SurfaceType.hxx>
 #include <GCPnts_QuasiUniformDeflection.hxx>
-#include <gp_Pnt.hxx>
-#include <gp_Pnt2d.hxx>
+#include <Geom2d_Curve.hxx>
+#include <Geom2dInt_Geom2dCurveTool.hxx>
+#include <GeomInt.hxx>
 #include <Precision.hxx>
-#include <TColgp_Array1OfPnt2d.hxx>
 #include <TColgp_SequenceOfPnt2d.hxx>
-#include <TopAbs_Orientation.hxx>
+#include <TColgp_SequenceOfVec2d.hxx>
+#include <TColStd_DataMapOfIntegerInteger.hxx>
 #include <TopExp.hxx>
 #include <TopExp_Explorer.hxx>
 #include <TopoDS.hxx>
 #include <TopoDS_Edge.hxx>
-#include <TopoDS_Face.hxx>
-
-#ifdef _MSC_VER
-#include <stdio.h>
-#endif
+#include <TopoDS_Vertex.hxx>
+#include <TopoDS_Wire.hxx>
 
+#include <NCollection_UBTree.hxx>
+#include <NCollection_UBTreeFiller.hxx>
+#include <Bnd_B2d.hxx>
 
-#ifdef OCCT_DEBUG
-#define LBRCOMPT 0
-#else
-#define LBRCOMPT 0
+//#define DEBUG_PCLASS_POLYGON
+#ifdef DEBUG_PCLASS_POLYGON
+#include <DrawTrSurf.hxx>
+#include <Geom2d_BSplineCurve.hxx>
 #endif
 
+typedef NCollection_UBTree<Standard_Integer, Bnd_B2d> BRepTopAdaptor_FClass2dTree;
+typedef NCollection_UBTreeFiller <Standard_Integer, Bnd_B2d> BRepTopAdaptor_FClass2dTreeFiller;
 
-#if LBRCOMPT  
-class StatistiquesFClass2d { 
-public:
-  long unsigned NbConstrShape;
-  long unsigned NbPerformInfinitePoint;
-  long unsigned NbPerform;
-  long unsigned NbTestOnRestriction;
-  long unsigned NbDestroy;
+inline Standard_Boolean IsInter1d(Standard_Real theU1, Standard_Real theU2,
+                                  Standard_Real theW1, Standard_Real theW2)
+{
+  if (theU1 > theU2)  std::swap(theU1, theU2);
+  if (theW1 > theW2)  std::swap(theW1, theW2);
+  return Max(theU1, theW1) - Min(theU2, theW2) < Precision::PConfusion();
+}
+
+class BRepTopAdaptor_FClass2dSel : public BRepTopAdaptor_FClass2dTree::Selector
+{
 public:
-  StatistiquesFClass2d() { 
-    NbConstrShape=NbPerform=NbPerformInfinitePoint=NbDestroy=0;
+  BRepTopAdaptor_FClass2dSel(const TColgp_Array1OfPnt2d& thePnts,
+                             const Bnd_B2d& theBox,
+                             const Standard_Integer theCurIdx) : 
+                             myPnts(thePnts),
+                             myBox(theBox),
+                             myNbSeg(myPnts.Length() - 1),
+                             myCurrentIndex(theCurIdx),
+                             myP1(myPnts(myCurrentIndex).XY()),
+                             myP2(myPnts(myCurrentIndex + 1).XY()),
+                             myVec12(myP2 - myP1)
+  {}
+
+  Standard_Boolean Reject(const Bnd_B2d& theBox) const
+  {
+    return theBox.IsOut(myBox);
   }
-  ~StatistiquesFClass2d() { 
-    printf("\n--- Statistiques BRepTopAdaptor:\n");
-    printf("\nConstructeur(Shape) : %10lu",NbConstrShape);
-    printf("\nPerformInfinitePoint: %10lu",NbPerformInfinitePoint);
-    printf("\nTestOnRestriction   : %10lu",NbTestOnRestriction);
-    printf("\nPerform(pnt2d)      : %10lu",NbPerform);
-    printf("\nDestroy             : %10lu",NbDestroy);
+
+  Standard_Boolean Accept(const Standard_Integer& theIndex)
+  {
+    // reject the same or neighboring index
+    if (myCurrentIndex == theIndex)
+      return Standard_False;
+    if ((myCurrentIndex % myNbSeg) + 1 == theIndex || (theIndex % myNbSeg) + 1 == myCurrentIndex)
+      return Standard_False;
+
+    const gp_XY& aP3 = myPnts(theIndex).XY();
+    const gp_XY& aP4 = myPnts(theIndex + 1).XY();
+
+    if (IsInter1d(myP1.X(), myP2.X(), aP3.X(), aP4.X()) &&
+        IsInter1d(myP1.Y(), myP2.Y(), aP3.Y(), aP4.Y()))
+    {
+      Standard_Real anAreaEps = Precision::PConfusion() * Precision::PConfusion();
+      gp_XY aVec13 = aP3 - myP1;
+      gp_XY aVec14 = aP4 - myP1;
+      if (myVec12.Crossed(aVec13) * myVec12.Crossed(aVec14) < anAreaEps)
+      {
+        gp_XY aVec34 = aP4 - aP3;
+        gp_XY aVec32 = myP2 - aP3;
+        if (aVec13.Crossed(aVec14) * aVec34.Crossed(aVec32) < anAreaEps)
+        {
+          myStop = Standard_True;
+          return Standard_True;
+        }
+      }
+    }
+    return Standard_False;
   }
-};
 
-static StatistiquesFClass2d STAT;
-#endif
+protected:
+  BRepTopAdaptor_FClass2dSel(BRepTopAdaptor_FClass2dSel&);
+  const BRepTopAdaptor_FClass2dSel& operator=(const BRepTopAdaptor_FClass2dSel&);
 
+private:
+  const TColgp_Array1OfPnt2d& myPnts;
+  Bnd_B2d myBox;
+  Standard_Integer myNbSeg, myCurrentIndex;
+  gp_XY myP1, myP2, myVec12;
+};
 
 
+//=======================================================================
+//function : Default constructor
+//purpose  : 
+//=======================================================================
+BRepTopAdaptor_FClass2d::BRepTopAdaptor_FClass2d() : myTol3D(Precision::Confusion()),
+                                                     myUmin(RealLast()),
+                                                     myVmin(RealLast()),
+                                                     myUmax(-myUmin),
+                                                     myVmax(-myVmin)
+{
+}
 
-BRepTopAdaptor_FClass2d::BRepTopAdaptor_FClass2d(const TopoDS_Face& aFace,const Standard_Real TolUV) 
-: Toluv(TolUV), Face(aFace)  { 
-  
-#if LBRCOMPT 
-  STAT.NbConstrShape++;
-#endif
+//=======================================================================
+//function : Constructor
+//purpose  : 
+//=======================================================================
+BRepTopAdaptor_FClass2d::BRepTopAdaptor_FClass2d(const TopoDS_Face& theFace,
+                                                 const Standard_Real theTol3D):
+                                                 myFace(theFace),
+                                                 myTol3D(theTol3D),
+                                                 myUmin(RealLast()), myVmin(RealLast()),
+                                                 myUmax(-myUmin), myVmax(-myVmin)
+{
+  Init(myFace, theTol3D);
+}
 
-  //-- dead end on surfaces defined on more than one period
+//=======================================================================
+//function : ComputeDeviation
+//purpose  : 
+//=======================================================================
+static Standard_Boolean ComputeDeviation(const gp_Pnt2d& thePf,
+                                         const gp_Pnt2d& thePl,
+                                         const gp_Pnt2d& thePm,
+                                         Standard_Real& theDU, Standard_Real& theDV)
+{
+  const gp_XY aDirVec = thePl.XY() - thePf.XY();
 
-  Face.Orientation(TopAbs_FORWARD);
-  Handle(BRepAdaptor_HSurface) surf = new BRepAdaptor_HSurface();
-  surf->ChangeSurface().Initialize(aFace,Standard_False);
-  
+  if (aDirVec.SquareModulus() > 1.0e-16)
+  {
+    const gp_Lin2d aLin(thePf, gp_Dir2d(aDirVec));
+    const Standard_Real aUmid = ElCLib::Parameter(aLin, thePm);
+    const gp_Pnt2d aPp = ElCLib::Value(aUmid, aLin);
+    theDU = Abs(aPp.X() - thePm.X());
+    theDV = Abs(aPp.Y() - thePm.Y());
+    return Standard_True;
+  }
+  return Standard_False;
+}
+
+//=======================================================================
+//function : Init
+//purpose  : 
+//=======================================================================
+void BRepTopAdaptor_FClass2d::Init(const TopoDS_Face& theFace,
+                                   const Standard_Real theTol3D)
+{
+  Standard_Boolean WireIsEmpty, Ancienpnt3dinitialise, degenerated;
+  Standard_Integer nbpnts, firstpoint, NbEdges;
+  Standard_Integer iX, aNbs1, nbs, Avant, BadWire;
+  Standard_Real u, du, pfbid, plbid;
+  Standard_Real FlecheU, FlecheV;
+  Standard_Real uFirst, uLast;
+  Standard_Real aPrCf, aPrCf2;
+  //
   TopoDS_Edge  edge;
+  TopoDS_Vertex Va, Vb;
   TopAbs_Orientation Or;
-  Standard_Real u,du,Tole = 0.0,Tol=0.0;
-  BRepTools_WireExplorer WireExplorer;
-  TopExp_Explorer FaceExplorer;
+  BRepTools_WireExplorer aWExp;
+  TopExp_Explorer aExpF, aExp;
+  Handle(Geom2d_Curve) aC2D;
+  gp_Pnt Ancienpnt3d;
+  TColgp_SequenceOfPnt2d SeqPnt2d;
+  
+  BRepAdaptor_Surface anAS(theFace, Standard_False);
+
+  Destroy();
 
-  Umin = Vmin = 0.0; //RealLast();
-  Umax = Vmax = -Umin;
+  aPrCf = Precision::Confusion();
+  aPrCf2 = aPrCf*aPrCf;
+  //
+  myFace = theFace;
+  myFace.Orientation(TopAbs_FORWARD);
+  myTol3D = theTol3D;
+  const Standard_Real aTolU = anAS.UResolution(theTol3D),
+                      aTolV = anAS.VResolution(theTol3D);
+  //const Standard_Real aMaxGapU = Max(aTolU, Precision::PConfusion());
+  //const Standard_Real aMaxGapV = Max(aTolV, Precision::PConfusion());
+  //
+  myUmin = myVmin = RealLast();
+  myUmax = myVmax = -myUmin;
+  BadWire = 0;
 
-  Standard_Integer BadWire=0;
-  for( FaceExplorer.Init(Face,TopAbs_WIRE); (FaceExplorer.More() && BadWire==0); FaceExplorer.Next() )
+  //if face has several wires and one of them is bad,
+  //it is necessary to process all of them for correct
+  //calculation of Umin, Umax, Vmin, Vmax - ifv, 23.08.06 
+  //
+  aExpF.Init(myFace, TopAbs_WIRE);
+  for (; aExpF.More(); aExpF.Next())
+  {
+    const TopoDS_Wire& aW = *((TopoDS_Wire*)&aExpF.Current());
+    //
+    nbpnts = 0;
+    firstpoint = 1;
+    FlecheU = aTolU;
+    FlecheV = aTolV;
+    WireIsEmpty = Standard_True;
+    Ancienpnt3dinitialise = Standard_False;
+    Ancienpnt3d.SetCoord(0., 0., 0.);
+    //
+    SeqPnt2d.Clear();
+    //
+    // NbEdges
+    NbEdges = 0;
+    aExp.Init(aW, TopAbs_EDGE);
+    for (; aExp.More(); aExp.Next())
     {
-      Standard_Integer nbpnts = 0;
-      TColgp_SequenceOfPnt2d SeqPnt2d;
-      Standard_Integer firstpoint = 1;
-      Standard_Real FlecheU = 0.0;
-      Standard_Real FlecheV = 0.0;
-      Standard_Boolean WireIsNotEmpty = Standard_False;
-      Standard_Integer NbEdges = 0;
-
-      TopExp_Explorer Explorer;
-      for( Explorer.Init(FaceExplorer.Current(),TopAbs_EDGE); Explorer.More(); Explorer.Next() ) NbEdges++;
-        
-      gp_Pnt Ancienpnt3d(0,0,0);
-      Standard_Boolean Ancienpnt3dinitialise = Standard_False;
-
-      for( WireExplorer.Init(TopoDS::Wire(FaceExplorer.Current()),Face); WireExplorer.More(); WireExplorer.Next() )
-	{
-	  
-	  NbEdges--;
-	  edge = WireExplorer.Current();
-	  Or = edge.Orientation();
-	  if(Or == TopAbs_FORWARD || Or == TopAbs_REVERSED)
-	    {
-	      Standard_Real pfbid,plbid;
-	      if(BRep_Tool::CurveOnSurface(edge,Face,pfbid,plbid).IsNull()) return;
-	      BRepAdaptor_Curve2d C(edge,Face);
-	
-	      //-- ----------------------------------------
-	      Standard_Boolean degenerated=Standard_False;
-	      if(BRep_Tool::Degenerated(edge))   degenerated=Standard_True;
-	      if(BRep_Tool::IsClosed(edge,Face)) degenerated=Standard_True;
-	      TopoDS_Vertex Va,Vb;
-	      TopExp::Vertices(edge,Va,Vb);
-	      Standard_Real TolVertex1=0.,TolVertex=0.;
-	      if (Va.IsNull()) degenerated=Standard_True;
-	      else TolVertex1=BRep_Tool::Tolerance(Va);
-	      if (Vb.IsNull()) degenerated=Standard_True;
-	      else TolVertex=BRep_Tool::Tolerance(Vb);
-	      if(TolVertex<TolVertex1) TolVertex=TolVertex1;
-	      BRepAdaptor_Curve C3d;
-	
-	      if(Abs(plbid-pfbid) < 1.e-9) continue;
-
-	      //if(degenerated==Standard_False)
-	      //  C3d.Initialize(edge,Face);
-
-	      //-- Check cases when it was forgotten to code degenerated :  PRO17410 (janv 99)
-	      if(degenerated == Standard_False)
-		{
-		  C3d.Initialize(edge,Face);
-		  du=(plbid-pfbid)*0.1;
-		  u=pfbid+du;
-		  gp_Pnt P3da=C3d.Value(u);
-		  degenerated=Standard_True;
-		  u+=du;
-		  do
-		    {
-		      
-		      gp_Pnt P3db=C3d.Value(u);
-		      // 		      if(P3da.SquareDistance(P3db)) { degenerated=Standard_False; break; }
-		      if(P3da.SquareDistance(P3db) > Precision::Confusion()) { degenerated=Standard_False; break; }
-		      u+=du;
-		    }
-		  while(u<plbid);
-		}
-	      
-	      //-- ----------------------------------------
-
-	      Tole = BRep_Tool::Tolerance(edge);
-	      if(Tole>Tol) Tol=Tole;
-	      
-	      //Standard_Integer nbs = 1 + Geom2dInt_Geom2dCurveTool::NbSamples(C);
-	      Standard_Integer nbs = Geom2dInt_Geom2dCurveTool::NbSamples(C);
-	      //-- Attention to rational bsplines of degree 3. (ends of circles among others)
-	      if (nbs > 2) nbs*=4;
-	      du = (plbid-pfbid)/(Standard_Real)(nbs-1);
-
-	      if(Or==TopAbs_FORWARD) u = pfbid;
-	      else { u = plbid; du=-du;	}
-	
-	      //-- ------------------------------------------------------------
-	      //-- Check distance uv between the start point of the edge
-	      //-- and the last point registered in SeqPnt2d
-	      //-- Try to remote the first point of the current edge 
-	      //-- from the last saved point
-#ifdef OCCT_DEBUG
-	      gp_Pnt2d Pnt2dDebutEdgeCourant = C.Value(u); (void)Pnt2dDebutEdgeCourant;
-#endif
+      const TopoDS_Edge& anE = TopoDS::Edge(aExp.Current());
+      const Standard_Real aTol = BRep_Tool::Tolerance(anE);
+      FlecheU = Max(FlecheU, anAS.UResolution(aTol));
+      FlecheV = Max(FlecheV, anAS.VResolution(aTol));
+      NbEdges++;
+    }
+
+    // First and last points of the previous edges
+    // in order to detect if wire is close in 2d-space
+    //gp_Pnt2d aPrevPoint, aFirstEPoint;
+    //Standard_Boolean isFirst = Standard_True;
+
+    //
+    aWExp.Init(aW, myFace);
+    for (; aWExp.More(); aWExp.Next()) {
+      NbEdges--;
+      edge = aWExp.Current();
+      Or = edge.Orientation();
+      if (!(Or == TopAbs_FORWARD || Or == TopAbs_REVERSED)) {
+        continue;
+      }
+      //
+      aC2D = BRep_Tool::CurveOnSurface(edge, myFace, pfbid, plbid);
+      if (aC2D.IsNull()) {
+        return;
+      }
+      //
+      BRepAdaptor_Curve2d C(edge, myFace);
+
+      //if (isFirst)
+      //{
+      //  C.D0(C.FirstParameter(), aFirstEPoint);
+      //  C.D0(C.LastParameter(), aPrevPoint);
+
+      //  if (edge.Orientation() == TopAbs_REVERSED)
+      //    std::swap(aFirstEPoint, aPrevPoint);
+      //}
+      //else
+      //{
+      //  gp_Pnt2d aP1(C.Value((Or == TopAbs_REVERSED) ? C.LastParameter() : C.FirstParameter()));
+      //  if (Abs(aP1.X() - aPrevPoint.X()) > aMaxGapU || Abs(aP1.Y() - aPrevPoint.Y()) > aMaxGapV)
+      //  {
+      //    //Wire is not closed in 2D-space
+      //    BadWire = 1;
+      //  }
+
+      //  C.D0((Or == TopAbs_REVERSED) ? C.FirstParameter() : C.LastParameter(), aPrevPoint);
+      //}
+
+      //isFirst = Standard_False;
+
+      BRepAdaptor_Curve C3d;
+      //------------------------------------------
+      degenerated = Standard_False;
+      if (BRep_Tool::Degenerated(edge) ||
+          BRep_Tool::IsClosed(edge, myFace))
+      {
+        degenerated = Standard_True;
+      }
+      //
+      TopExp::Vertices(edge, Va, Vb);
+      //
+      if (Va.IsNull() || Vb.IsNull())
+      {
+        degenerated = Standard_True;
+      }
+      //
+      //-- Verification of cases when forgotten to code degenereted
+      if (!degenerated) {
+        // check that whole curve is located in vicinity of its middle point
+        // (within sphere of Precision::Confusion() diameter)
+        C3d.Initialize(edge, myFace);
+        gp_Pnt P3da = C3d.Value(0.5 * (pfbid + plbid));
+        du = plbid - pfbid;
+        const int NBSTEPS = 10;
+        Standard_Real aPrec2 = 0.25 * Precision::Confusion() * Precision::Confusion();
+        degenerated = Standard_True;
+        for (Standard_Integer i = 0; i <= NBSTEPS; i++)
+        {
+          Standard_Real U = pfbid + i * du / NBSTEPS;
+          gp_Pnt P3db = C3d.Value(U);
+          Standard_Real aR2 = P3da.SquareDistance(P3db);
+          if (aR2 > aPrec2) {
+            degenerated = Standard_False;
+            break;
+          }
+        }
+      }//if(!degenerated)
+      //-- ----------------------------------------
+      //
+      // NbSamples +> nbs
+      nbs = Geom2dInt_Geom2dCurveTool::NbSamples(C);
+      if (nbs > 2) {
+        nbs *= 4;
+      }
+      du = (plbid - pfbid) / (Standard_Real)(nbs - 1);
+      //
+      if (Or == TopAbs_FORWARD) {
+        u = pfbid;
+        uFirst = pfbid;
+        uLast = plbid;
+      }
+      else {
+        u = plbid;
+        uFirst = plbid;
+        uLast = pfbid;
+        du = -du;
+      }
+      //
+      // aPrms
+      aNbs1 = (nbs == 2 ? nbs + 1 : nbs);
+      TColStd_Array1OfReal aPrms(1, aNbs1);
+      //
+      if (nbs == 2) {
+        Standard_Real aCoef = 0.0025;
+        aPrms(1) = uFirst;
+        aPrms(2) = uFirst + aCoef*(uLast - uFirst);
+        aPrms(3) = uLast;
+      }
+      else if (nbs>2) {
+        aNbs1 = nbs;
+        aPrms(1) = uFirst;
+        for (iX = 2; iX<aNbs1; ++iX) {
+          aPrms(iX) = u + (iX - 1)*du;
+        }
+        aPrms(aNbs1) = uLast;
+      }
+      //
+      //-- ------------------------------------------------------------
+      //-- Check distance uv between the start point of the edge
+      //-- and the last point saved in SeqPnt2d
+      //-- To to set the first point of the current 
+      //-- afar from the last saved point
+      Avant = nbpnts;
+      for (iX = firstpoint; iX <= aNbs1; iX++) {
+        Standard_Boolean IsRealCurve3d;
+        Standard_Integer ii;
+        Standard_Real aDstX;
+        gp_Pnt2d P2d;
+        gp_Pnt P3d;
+        //
+        u = aPrms(iX);
+        P2d = C.Value(u);
+        if(P2d.X()<myUmin) myUmin = P2d.X();
+        if(P2d.X()>myUmax) myUmax = P2d.X();
+        if(P2d.Y()<myVmin) myVmin = P2d.Y();
+        if(P2d.Y()>myVmax) myVmax = P2d.Y();
+        //
+        aDstX = RealLast();
+        if (degenerated == Standard_False) {
+          P3d = C3d.Value(u);
+          if (nbpnts>1) {
+            if (Ancienpnt3dinitialise) {
+              aDstX = P3d.SquareDistance(Ancienpnt3d);
+            }
+          }
+        }
+        //
+        IsRealCurve3d = Standard_True;
+        if (aDstX < aPrCf2)  {
+          if (iX>1) {
+            Standard_Real aDstX1;
+            gp_Pnt MidP3d;
+            //
+            MidP3d = C3d.Value(0.5*(u + aPrms(iX - 1)));
+            aDstX1 = P3d.SquareDistance(MidP3d);
+            if (aDstX1 < aPrCf2){
+              IsRealCurve3d = Standard_False;
+            }
+          }
+        }
+        //
+        if (IsRealCurve3d) {
+          if (degenerated == Standard_False) {
+            Ancienpnt3d = P3d;
+            Ancienpnt3dinitialise = Standard_True;
+          }
+          nbpnts++;
+          SeqPnt2d.Append(P2d);
+        }
+        //
+        ii = nbpnts;
+        if (ii>(Avant + 4)) {
+          const gp_Pnt2d &aPpf = SeqPnt2d(ii - 2),
+                         &aPpl = SeqPnt2d(ii),
+                         &aPpm = SeqPnt2d(ii - 1);
+          Standard_Real aDU, aDV;
+          if (ComputeDeviation(aPpf, aPpl, aPpm, aDU, aDV))
+          {
+            if (aDU > FlecheU)
+              FlecheU = aDU;
+            if (aDV > FlecheV)
+              FlecheV = aDV;
+          }
+        }
+        else if (firstpoint == 2 && iX == 2)
+        {
+          // compute deflection of skipped beginning of the curve to the created polygon
+          const gp_Pnt2d &aPpf = SeqPnt2d(ii - 1),
+                         &aPpl = SeqPnt2d(ii);
+          const gp_Pnt2d aPpm = C.Value(aPrms(1));
+          Standard_Real aDU, aDV;
+          if (ComputeDeviation(aPpf, aPpl, aPpm, aDU, aDV))
+          {
+            if (aDU > FlecheU)
+              FlecheU = aDU;
+            if (aDV > FlecheV)
+              FlecheV = aDV;
+          }
+        }
+      }// for(iX=firstpoint; iX<=aNbs1; iX++) {
+      //
+      if (BadWire) {
+        continue; //if face has several wires and one of them is bad,
+        //it is necessary to process all of them for correct
+        //calculation of Umin, Umax, Vmin, Vmax - ifv, 23.08.06 
+      }
+      //
+      if (firstpoint == 1)
+        firstpoint = 2;
+
+      WireIsEmpty = Standard_False;
+    } //for(;aWExp.More(); aWExp.Next()) {
+    // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+    if (NbEdges/* || Abs(aFirstEPoint.X() - aPrevPoint.X()) > aMaxGapU ||
+                   Abs(aFirstEPoint.Y() - aPrevPoint.Y()) > aMaxGapV*/)
+    {
+      // 1. TopExp_Explorer and BRepTools_WireExplorer returns differ number of edges
+      // 2. Wire is not closed in 2D-space
+      TColgp_Array1OfPnt2d PClass(1, 2);
+      gp_Pnt2d anInitPnt(0., 0.);
+      //
+      PClass.Init(anInitPnt);
+      myTabClass.Append(new CSLib_Class2d(PClass,
+                                          FlecheU,
+                                          FlecheV,
+                                          myUmin, myVmin, myUmax, myVmax));
+      BadWire = 1;
+      myTabOrien.Append(-1);
+    }
+    //
+    else if (!WireIsEmpty)
+    {
+      Standard_Real anArea = 0.0;
+      TColgp_Array1OfPnt2d PClass(1, nbpnts);
+      gp_Pnt2d anInitPnt(0., 0.);
+      //
+      PClass.Init(anInitPnt);
+      if (nbpnts <= 3)
+      {
+        BadWire = 1;
+      }
+      
+      if (!BadWire)
+      {
+        // Point to area computation
+        const Standard_Integer im2 = nbpnts - 2;
+        Standard_Integer im1 = nbpnts - 1;
+        Standard_Integer im0 = 1;
+        //
+        PClass(im2) = SeqPnt2d.Value(im2);
+        PClass(im1) = SeqPnt2d.Value(im1);
+        PClass(nbpnts) = SeqPnt2d.Value(nbpnts);
+
+        Standard_Real aPer = 0.;
+        for (Standard_Integer ii = 1; ii<nbpnts; ii++, im0++, im1++)
+        {
+          if (im1 >= nbpnts) im1 = 1;
+          PClass(ii) = SeqPnt2d.Value(ii);
+
+          const gp_Pnt2d& aP2D1=PClass(im1);
+          const gp_Pnt2d& aP2D0=PClass(im0);
+          //aP2D0 is next to aP2D1
+          const gp_Vec2d A(PClass(1/*im2*/), aP2D1);
+          const gp_Vec2d B(aP2D1, aP2D0);
+          anArea += A.Crossed(B);
+          aPer += aP2D1.Distance(aP2D0);
+        }//for (Standard_Integer ii = 1; ii<nbpnts; ii++, im0++, im1++)
 
-	      //Standard_Real Baillement2dU=0;
-	      //Standard_Real Baillement2dV=0;
-#if AFFICHAGE
-	      if(nbpnts>1) printf("\nTolVertex %g ",TolVertex);
+#ifdef DEBUG_PCLASS_POLYGON
+        TColStd_Array1OfReal aKnots(1, nbpnts);
+        TColStd_Array1OfInteger aMults(1, nbpnts);
+        for (int i = 1; i <= nbpnts; i++)
+        {
+          aKnots(i) = i;
+          aMults(i) = 1;
+        }
+        aMults(1) = aMults(nbpnts) = 2;
+        Handle(Geom2d_BSplineCurve) aPol = new Geom2d_BSplineCurve(PClass, aKnots, aMults, 1);
+        DrawTrSurf::Set("pol", aPol);
 #endif
 
-	      if(firstpoint==2) u+=du;
-	      Standard_Integer Avant = nbpnts;
-	      for(Standard_Integer e = firstpoint; e<=nbs; e++)
-		{
-		  gp_Pnt2d P2d = C.Value(u);
-		  if(P2d.X()<Umin) Umin = P2d.X();
-		  if(P2d.X()>Umax) Umax = P2d.X();
-		  if(P2d.Y()<Vmin) Vmin = P2d.Y();
-		  if(P2d.Y()>Vmax) Vmax = P2d.Y();
-	  
-		  Standard_Real dist3dptcourant_ancienpnt=1e+20;//RealLast();
-		  gp_Pnt P3d;
-		  if(degenerated==Standard_False)
-		    {
-		      P3d=C3d.Value(u);
-		      if(nbpnts>1 && Ancienpnt3dinitialise) dist3dptcourant_ancienpnt = P3d.Distance(Ancienpnt3d);
-		    }
-		  Standard_Boolean IsRealCurve3d = Standard_True; //patch
-		  if(dist3dptcourant_ancienpnt < Precision::Confusion())
-		    {
-		      gp_Pnt MidP3d = C3d.Value( u-du/2. );
-		      if (P3d.Distance( MidP3d ) < Precision::Confusion()) IsRealCurve3d = Standard_False;
-		    }
-		  if(IsRealCurve3d)
-		    {
-		      if(degenerated==Standard_False) { Ancienpnt3d=P3d;  Ancienpnt3dinitialise=Standard_True; }
-		      nbpnts++;
-		      SeqPnt2d.Append(P2d);
-		    }
-#if AFFICHAGE
-                  else { static int mm=0; printf("\npoint p%d  %g %g %g",++mm,P3d.X(),P3d.Y(),P3d.Z());	}
+        {
+          const Standard_Real aToler = Max(myTol3D, Precision::Confusion());
+          if (Abs(anArea) < aToler*aToler)
+          {
+            // anArea = |A|*|B|*sin(Angle) < Tol*Tol
+            anArea = 0.;
+            BadWire = 1;
+          }
+        }
+
+        if (!BadWire)
+        {
+#ifdef DEBUG_PCLASS_POLYGON
+        TColStd_Array1OfReal aKnots(1, nbpnts);
+        TColStd_Array1OfInteger aMults(1, nbpnts);
+        for (int i = 1; i <= nbpnts; i++)
+        {
+          aKnots(i) = i;
+          aMults(i) = 1;
+        }
+        aMults(1) = aMults(nbpnts) = 2;
+        Handle(Geom2d_BSplineCurve) aPol = new Geom2d_BSplineCurve(PClass, aKnots, aMults, 1);
+        DrawTrSurf::Set("pol", aPol);
 #endif
-		  u+=du;
-		  Standard_Integer ii = nbpnts;
-		  //-- printf("\n nbpnts:%4d  u=%7.5g   FlecheU=%7.5g  FlecheV=%7.5g  ii=%3d  Avant=%3d ",nbpnts,u,FlecheU,FlecheV,ii,Avant);
-// 		  if(ii>(Avant+4))
-//  Modified by Sergey KHROMOV - Fri Apr 19 09:46:12 2002 Begin
-		  if(ii>(Avant+4) && SeqPnt2d(ii-2).SquareDistance(SeqPnt2d(ii)))
-//  Modified by Sergey KHROMOV - Fri Apr 19 09:46:13 2002 End
-		    {
-		      gp_Lin2d Lin(SeqPnt2d(ii-2),gp_Dir2d(gp_Vec2d(SeqPnt2d(ii-2),SeqPnt2d(ii))));
-		      Standard_Real ul = ElCLib::Parameter(Lin,SeqPnt2d(ii-1));
-		      gp_Pnt2d Pp = ElCLib::Value(ul,Lin);
-		      Standard_Real dU = Abs(Pp.X()-SeqPnt2d(ii-1).X());
-		      Standard_Real dV = Abs(Pp.Y()-SeqPnt2d(ii-1).Y());
-		      //-- printf(" (du=%7.5g   dv=%7.5g)",dU,dV);
-		      if(dU>FlecheU) FlecheU = dU;
-		      if(dV>FlecheV) FlecheV = dV;
-		    }
-		}//for(e=firstpoint
-	      if(firstpoint==1) firstpoint=2;
-	      WireIsNotEmpty = Standard_True;
-	    }//if(Or==FORWARD,REVERSED
-	} //-- Edges -> for(Ware.Explorer
-
-      if(NbEdges)
-	{ //-- on compte ++ with a normal explorer and with the Wire Explorer
-/*
-#ifdef OCCT_DEBUG
-
-	  cout << endl;
-	  cout << "*** BRepTopAdaptor_Fclass2d  ** Wire Probablement FAUX **" << endl;
-	  cout << "*** WireExplorer does not find all edges " << endl;
-	  cout << "*** Connect old classifier" << endl;
+
+        Standard_Real anExpThick = Max(2. * Abs(anArea) / aPer, 1e-7);
+        Standard_Real aDefl = Max(FlecheU, FlecheV);
+        Standard_Real aDiscrDefl = Min(aDefl*0.1, anExpThick * 10.);
+        while (aDefl > anExpThick && aDiscrDefl > 1e-7)
+        {
+          // Deflection of the polygon is too much for this ratio of area and perimeter,
+          // and this might lead to self-intersections.
+          // Discretize the wire more tightly to eliminate the error.
+          firstpoint = 1;
+          SeqPnt2d.Clear();
+          FlecheU = 0.0;
+          FlecheV = 0.0;
+          for (aWExp.Init(TopoDS::Wire(aExpF.Current()), myFace);
+            aWExp.More(); aWExp.Next())
+          {
+            edge = aWExp.Current();
+            Or = edge.Orientation();
+            if (Or == TopAbs_FORWARD || Or == TopAbs_REVERSED)
+            {
+              BRep_Tool::Range(edge, myFace, pfbid, plbid);
+              if (Abs(plbid - pfbid) < 1.e-9) continue;
+              BRepAdaptor_Curve2d C(edge, myFace);
+              GCPnts_QuasiUniformDeflection aDiscr(C, aDiscrDefl);
+              if (!aDiscr.IsDone())
+                break;
+              Standard_Integer nbp = aDiscr.NbPoints();
+              Standard_Integer iStep = 1, i = 1, iEnd = nbp + 1;
+              if (Or == TopAbs_REVERSED)
+              {
+                iStep = -1;
+                i = nbp;
+                iEnd = 0;
+              }
+              if (firstpoint == 2)
+                i += iStep;
+              for (; i != iEnd; i += iStep)
+              {
+                gp_Pnt2d aP2d = C.Value(aDiscr.Parameter(i));
+                SeqPnt2d.Append(aP2d);
+              }
+              if (nbp > 2)
+              {
+                Standard_Integer ii = SeqPnt2d.Length();
+                gp_Lin2d Lin(SeqPnt2d(ii - 2), gp_Dir2d(gp_Vec2d(SeqPnt2d(ii - 2), SeqPnt2d(ii))));
+                Standard_Real ul = ElCLib::Parameter(Lin, SeqPnt2d(ii - 1));
+                gp_Pnt2d Pp = ElCLib::Value(ul, Lin);
+                Standard_Real dU = Abs(Pp.X() - SeqPnt2d(ii - 1).X());
+                Standard_Real dV = Abs(Pp.Y() - SeqPnt2d(ii - 1).Y());
+                if (dU > FlecheU) FlecheU = dU;
+                if (dV > FlecheV) FlecheV = dV;
+              }
+              firstpoint = 2;
+            }
+          }
+          nbpnts = SeqPnt2d.Length();
+          PClass.Resize(1, nbpnts, Standard_False);
+          im1 = nbpnts - 1;
+          im0 = 1;
+          PClass(im1) = SeqPnt2d.Value(im1);
+          PClass(nbpnts) = SeqPnt2d.Value(nbpnts);
+          anArea = 0.;
+          aPer = 0.;
+          for (Standard_Integer ii = 1; ii<nbpnts; ii++, im0++, im1++)
+          {
+            if (im1 >= nbpnts) im1 = 1;
+            PClass(ii) = SeqPnt2d.Value(ii);
+            anArea += (PClass(im1).X() - PClass(im0).X())*(PClass(im0).Y() + PClass(im1).Y())*.5;
+            aPer += (PClass(im0).XY() - PClass(im1).XY()).Modulus();
+          }
+#ifdef DEBUG_PCLASS_POLYGON
+          TColStd_Array1OfReal aKnots(1, nbpnts);
+          TColStd_Array1OfInteger aMults(1, nbpnts);
+          for (int i = 1; i <= nbpnts; i++)
+          {
+            aKnots(i) = i;
+            aMults(i) = 1;
+          }
+          aMults(1) = aMults(nbpnts) = 2;
+          Handle(Geom2d_BSplineCurve) aPol = new Geom2d_BSplineCurve(PClass, aKnots, aMults, 1);
+          DrawTrSurf::Set("pol1", aPol);
 #endif
-*/
-	  TColgp_Array1OfPnt2d PClass(1,2);
-	  //// modified by jgv, 28.04.2009 ////
-	  PClass.Init(gp_Pnt2d(0.,0.));
-	  /////////////////////////////////////
-	  TabClass.Append((void *)new CSLib_Class2d(PClass,FlecheU,FlecheV,Umin,Vmin,Umax,Vmax));
-	  BadWire=1;
-	  TabOrien.Append(-1);
-	}
-      else if(WireIsNotEmpty)
-	{
-	  //Standard_Real anglep=0,anglem=0;
-	  TColgp_Array1OfPnt2d PClass(1,nbpnts);
-	  Standard_Real square = 0.0;
-
-	  //-------------------------------------------------------------------
-	  //-- ** The mode of calculation was somewhat changed 
-	  //-- Before Oct 31 97 , the total angle of  
-	  //-- rotation of the wire was evaluated on all angles except for the last 
-	  //-- ** Now, exactly the angle of rotation is evaluated
-	  //-- If a value remote from 2PI or -2PI is found, it means that there is 
-	  //-- an uneven number of loops
-
-	  if(nbpnts>3)
-	    {
-//	      Standard_Integer im2=nbpnts-2;
-	      Standard_Integer im1=nbpnts-1;
-	      Standard_Integer im0=1;
-//	      PClass(im2)=SeqPnt2d.Value(im2);
-	      PClass(im1)=SeqPnt2d.Value(im1);
-	      PClass(nbpnts)=SeqPnt2d.Value(nbpnts);
-
-              Standard_Real aPer = 0.;
-//	      for(Standard_Integer ii=1; ii<nbpnts; ii++,im0++,im1++,im2++)
-	      for(Standard_Integer ii=1; ii<nbpnts; ii++,im0++,im1++)
-		{ 
-//		  if(im2>=nbpnts) im2=1;
-		  if(im1>=nbpnts) im1=1;
-		  PClass(ii)=SeqPnt2d.Value(ii);
-//		  gp_Vec2d A(PClass(im2),PClass(im1));
-//		  gp_Vec2d B(PClass(im1),PClass(im0));
-//		  Standard_Real N = A.Magnitude() * B.Magnitude();
-
-		  square += (PClass(im0).X()-PClass(im1).X())*(PClass(im0).Y()+PClass(im1).Y())*.5; 
-                  aPer += (PClass(im0).XY() - PClass(im1).XY()).Modulus();
-
-//		  if(N>1e-16){ Standard_Real a=A.Angle(B); angle+=a; }
-		}
-
-              Standard_Real anExpThick = Max(2. * Abs(square) / aPer, 1e-7);
-              Standard_Real aDefl = Max(FlecheU, FlecheV);
-              Standard_Real aDiscrDefl = Min(aDefl*0.1, anExpThick * 10.);
-              while (aDefl > anExpThick && aDiscrDefl > 1e-7)
+
+          anExpThick = Max(2. * Abs(anArea) / aPer, 1e-7);
+          aDefl = Max(FlecheU, FlecheV);
+          aDiscrDefl = Min(aDiscrDefl * 0.1, anExpThick * 10.);
+        }
+      }
+        
+        if (!BadWire)
+        {
+          NCollection_Array1<Bnd_B2d> anArrBoxes(1, nbpnts - 1);
+          anArrBoxes(im2).Add(PClass(im2));
+          anArrBoxes(im2).Add(PClass(im1));
+          anArrBoxes(im1).Add(PClass(im1));
+          anArrBoxes(im1).Add(PClass(nbpnts));
+          for (Standard_Integer ii = 1; ii < nbpnts; ii++)
+          {
+            anArrBoxes(ii).Add(PClass(ii));
+            anArrBoxes(ii).Add(PClass(ii + 1));
+          }
+
+          if (nbpnts > 100)
+          {
+            BRepTopAdaptor_FClass2dTree aBBTree;
+            {
+              BRepTopAdaptor_FClass2dTreeFiller aTreeFiller(aBBTree);
+              for (Standard_Integer ii = 1; ii < nbpnts; ii++)
+                aTreeFiller.Add(ii, anArrBoxes(ii));
+            }
+            for (Standard_Integer ii = 1; ii < nbpnts; ii++)
+            {
+              const Bnd_B2d& aBox = anArrBoxes(ii);
+              BRepTopAdaptor_FClass2dSel aSelector(PClass, aBox, ii);
+              if (aBBTree.Select(aSelector))
               {
-                // Deflection of the polygon is too much for this ratio of area and perimeter,
-                // and this might lead to self-intersections.
-                // Discretize the wire more tightly to eliminate the error.
-                firstpoint = 1;
-                SeqPnt2d.Clear();
-                FlecheU = 0.0;
-                FlecheV = 0.0;
-                for (WireExplorer.Init(TopoDS::Wire(FaceExplorer.Current()), Face);
-                  WireExplorer.More(); WireExplorer.Next())
-                {
-                  edge = WireExplorer.Current();
-                  Or = edge.Orientation();
-                  if (Or == TopAbs_FORWARD || Or == TopAbs_REVERSED)
-                  {
-                    Standard_Real pfbid, plbid;
-                    BRep_Tool::Range(edge, Face, pfbid, plbid);
-                    if (Abs(plbid - pfbid) < 1.e-9) continue;
-                    BRepAdaptor_Curve2d C(edge, Face);
-                    GCPnts_QuasiUniformDeflection aDiscr(C, aDiscrDefl);
-                    if (!aDiscr.IsDone())
-                      break;
-                    Standard_Integer nbp = aDiscr.NbPoints();
-                    Standard_Integer iStep = 1, i = 1, iEnd = nbp + 1;
-                    if (Or == TopAbs_REVERSED)
-                    {
-                      iStep = -1;
-                      i = nbp;
-                      iEnd = 0;
-                    }
-                    if (firstpoint == 2)
-                      i += iStep;
-                    for (; i != iEnd; i += iStep)
-                    {
-                      gp_Pnt2d aP2d = C.Value(aDiscr.Parameter(i));
-                      SeqPnt2d.Append(aP2d);
-                    }
-                    if (nbp > 2)
-                    {
-                      Standard_Integer ii = SeqPnt2d.Length();
-                      gp_Lin2d Lin(SeqPnt2d(ii - 2), gp_Dir2d(gp_Vec2d(SeqPnt2d(ii - 2), SeqPnt2d(ii))));
-                      Standard_Real ul = ElCLib::Parameter(Lin, SeqPnt2d(ii - 1));
-                      gp_Pnt2d Pp = ElCLib::Value(ul, Lin);
-                      Standard_Real dU = Abs(Pp.X() - SeqPnt2d(ii - 1).X());
-                      Standard_Real dV = Abs(Pp.Y() - SeqPnt2d(ii - 1).Y());
-                      if (dU > FlecheU) FlecheU = dU;
-                      if (dV > FlecheV) FlecheV = dV;
-                    }
-                    firstpoint = 2;
-                  }
-                }
-                nbpnts = SeqPnt2d.Length();
-                PClass.Resize(1, nbpnts, Standard_False);
-                im1 = nbpnts - 1;
-                im0 = 1;
-                PClass(im1) = SeqPnt2d.Value(im1);
-                PClass(nbpnts) = SeqPnt2d.Value(nbpnts);
-                square = 0.;
-                aPer = 0.;
-                for (Standard_Integer ii = 1; ii<nbpnts; ii++, im0++, im1++)
+                //The polygon is self-intersected
+                BadWire = Standard_True;
+                break;
+              }
+            }
+          }
+          else
+          {
+            for (Standard_Integer ii = 1; ii < nbpnts; ii++)
+            {
+              const Bnd_B2d& aBox = anArrBoxes(ii);
+              BRepTopAdaptor_FClass2dSel aSelector(PClass, aBox, ii);
+              for (Standard_Integer j = ii + 1; j < nbpnts; j++)
+              {
+                const Bnd_B2d& aBoxj = anArrBoxes(j);
+                if (!aSelector.Reject(aBoxj) && aSelector.Accept(j))
                 {
-                  if (im1 >= nbpnts) im1 = 1;
-                  PClass(ii) = SeqPnt2d.Value(ii);
-                  square += (PClass(im0).X() - PClass(im1).X())*(PClass(im0).Y() + PClass(im1).Y())*.5;
-                  aPer += (PClass(im0).XY() - PClass(im1).XY()).Modulus();
+                  //The polygon is self-intersected
+                  BadWire = Standard_True;
+                  break;
                 }
-
-                anExpThick = Max(2. * Abs(square) / aPer, 1e-7);
-                aDefl = Max(FlecheU, FlecheV);
-                aDiscrDefl = Min(aDiscrDefl * 0.1, anExpThick * 10.);
               }
-      
-	      //-- FlecheU*=10.0;
-	      //-- FlecheV*=10.0;
-	      if(FlecheU<Toluv) FlecheU = Toluv;
-	      if(FlecheV<Toluv) FlecheV = Toluv;
-	      //-- cout<<" U:"<<FlecheU<<" V:"<<FlecheV<<endl;
-	      TabClass.Append((void *)new CSLib_Class2d(PClass,FlecheU,FlecheV,Umin,Vmin,Umax,Vmax));
-
-//	      if((angle<2 && angle>-2)||(angle>10)||(angle<-10))
-//		{
-//		  BadWire=1;
-//		  TabOrien.Append(-1);
-//#ifdef OCCT_DEBUG
-//		  cout << endl;
-//		  cout << "*** BRepTopAdaptor_Fclass2d  ** Wire Probably FALSE **" << endl;
-//		  cout << "*** Total rotation angle of the wire : " << angle << endl;
-//		  cout << "*** Connect the old classifier" << endl;
-//#endif
-//		} 
-//	      else TabOrien.Append(((angle>0.0)? 1 : 0));
-	      TabOrien.Append(((square < 0.0)? 1 : 0));
-	    }//if(nbpoints>3
-	  else
-	    { 
-#ifdef OCCT_DEBUG
-	      cout << endl;
-	      cout << "*** BRepTopAdaptor_Fclass2d  ** Wire Probably FALSE **" << endl;
-	      cout << "*** The sample wire contains less than 3 points" << endl;
-	      cout << "*** Connect the old classifier" << endl;
-#endif       
-	      BadWire=1;
-	      TabOrien.Append(-1);
-	      TColgp_Array1OfPnt2d xPClass(1,2);
-	      xPClass(1) = SeqPnt2d(1); 
-	      xPClass(2) = SeqPnt2d(2);
-	      TabClass.Append((void *)new CSLib_Class2d(xPClass,FlecheU,FlecheV,Umin,Vmin,Umax,Vmax));
-	    }
-	}//else if(WareIsNotEmpty
-  }//for(FaceExplorer
-
-  Standard_Integer nbtabclass = TabClass.Length();
-
-  if(nbtabclass>0)
-    {
-      //-- If an error was detected on a wire: set all TabOrien to -1
-      if(BadWire) TabOrien(1)=-1;
-
-      if(   surf->GetType()==GeomAbs_Cone
-	 || surf->GetType()==GeomAbs_Cylinder
-	 || surf->GetType()==GeomAbs_Torus
-	 || surf->GetType()==GeomAbs_Sphere
-	 || surf->GetType()==GeomAbs_SurfaceOfRevolution)
-	
-	{
-	  Standard_Real uuu=M_PI+M_PI-(Umax-Umin);
-	  if(uuu<0) uuu=0;
-	  U1 = 0.0;  // modified by NIZHNY-OFV  Thu May 31 14:24:10 2001 ---> //Umin-uuu*0.5;
-	  U2 = 2*M_PI; // modified by NIZHNY-OFV  Thu May 31 14:24:35 2001 ---> //U1+M_PI+M_PI;
-	}
-      else { U1=U2=0.0; } 
-    
-      if(surf->GetType()==GeomAbs_Torus)
-	{ 
-	  Standard_Real uuu=M_PI+M_PI-(Vmax-Vmin);
-	  if(uuu<0) uuu=0;
-	  V1 = 0.0;  // modified by NIZHNY-OFV  Thu May 31 14:24:55 2001 ---> //Vmin-uuu*0.5;
-	  V2 = 2*M_PI; // modified by NIZHNY-OFV  Thu May 31 14:24:59 2001 ---> //V1+M_PI+M_PI;
-	}
-      else { V1=V2=0.0; }   
-    }
-}
+            }
+          }
+        } // if (!BadWire) cond.
+      } // if (!BadWire) cond.
 
-TopAbs_State BRepTopAdaptor_FClass2d::PerformInfinitePoint() const { 
-#if LBRCOMPT 
-  STAT.NbPerformInfinitePoint++;
-#endif
-  
-  if(Umax==-RealLast() || Vmax==-RealLast() || Umin==RealLast() || Vmin==RealLast()) { 
-    return(TopAbs_IN);
+      if (!BadWire)
+      {
+        myTabClass.Append(new CSLib_Class2d(PClass,
+                                            FlecheU, FlecheV,
+                                            myUmin, myVmin, myUmax, myVmax));
+
+        myTabOrien.Append((anArea > 0.0) ? 1 : 0);
+      }
+      else // if (BadWire)
+      {
+        myTabOrien.Append(-1);
+        TColgp_Array1OfPnt2d PPClass(1, 2);
+        myTabClass.Append(new CSLib_Class2d(PPClass,
+                                            FlecheU,
+                                            FlecheV,
+                                            myUmin, myVmin, myUmax, myVmax));
+      }
+    }// else if(!WireIsEmpty) cond.
+  } // for(; aExpF.More();  aExpF.Next()) {
+
+  if((myTabClass.Length() > 0) && (BadWire))
+  {
+    //-- if an error on a wire was detected : all TabOrien set to -1
+    myTabOrien(1) = -1;
   }
-  gp_Pnt2d P(Umin-(Umax-Umin),Vmin-(Vmax-Vmin));
-  return(Perform(P,Standard_False));
 }
 
-TopAbs_State BRepTopAdaptor_FClass2d::Perform(const gp_Pnt2d& _Puv,
-					      const Standard_Boolean RecadreOnPeriodic) const
-{ 
-#if LBRCOMPT 
-  STAT.NbPerform++;
-#endif
-  
-  Standard_Integer dedans;
-  Standard_Integer nbtabclass = TabClass.Length();
-  
-  if(nbtabclass==0) { 
-    return(TopAbs_IN);
+//=======================================================================
+//function : PerformInfinitePoint
+//purpose  : 
+//=======================================================================
+TopAbs_State BRepTopAdaptor_FClass2d::PerformInfinitePoint() const
+{
+  if(myUmax == -RealLast() || myVmax == -RealLast() ||
+     myUmin == RealLast() || myVmin == RealLast())
+  {
+    return TopAbs_IN;
   }
-  
-  //-- U1 is the First Param and U2 in this case is U1+Period
-  Standard_Real u=_Puv.X();
-  Standard_Real v=_Puv.Y();
-  Standard_Real uu = u, vv = v;
-
-  Handle(BRepAdaptor_HSurface) surf = new BRepAdaptor_HSurface();
-  surf->ChangeSurface().Initialize( Face, Standard_False );
-  const Standard_Boolean IsUPer  = surf->IsUPeriodic();
-  const Standard_Boolean IsVPer  = surf->IsVPeriodic();
-  const Standard_Real    uperiod = IsUPer ? surf->UPeriod() : 0.0;
-  const Standard_Real    vperiod = IsVPer ? surf->VPeriod() : 0.0;
-  TopAbs_State aStatus = TopAbs_UNKNOWN;
-  Standard_Boolean urecadre = Standard_False, vrecadre = Standard_False;
 
-  if (RecadreOnPeriodic)
+  const Standard_Real aMaxTol = Min(10.0, BRep_Tool::MaxTolerance(myFace,
+                                                                  TopAbs_VERTEX));
+  const BRepAdaptor_Surface aS(myFace, Standard_False);
+  gp_Pnt2d aP;
+
+  // For periodic surfaces, Umax - Umin (or Vmax - Vmin)
+  // can be equal to period. In this case, shift on 
+  // k*(Umax - Umin), where k is an integer number,
+  // will not take any effect in 3D-space. Therefore, we apply
+  // that k is not integer.
+  const Standard_Real aDeltaU = 1.5*(myUmax - myUmin),
+                      aDeltaV = 1.5*(myVmax - myVmin);
+
+  if (aDeltaU < aDeltaV)
+  {
+    aP.SetCoord((myUmin - Max(aDeltaU + 2.0*aS.UResolution(aMaxTol), 1.0)),
+                                                        0.5*(myVmax + myVmin));
+
+    //In order to avoid work with infinite-located curves (e.g. in
+    //half-spaces)
+    if(Precision::IsInfinite(myVmax) && Precision::IsInfinite(myVmin))
+    {
+      aP.SetY(0.0);
+    }
+    else if(Precision::IsInfinite(myVmax))
     {
-      if (IsUPer)
-	{
-	  if (uu < Umin)
-	    while (uu < Umin)
-	      uu += uperiod;
-	  else
-	    {
-	      while (uu >= Umin)
-		uu -= uperiod;
-	      uu += uperiod;
-	    }
-	}
-      if (IsVPer)
-	{
-	  if (vv < Vmin)
-	    while (vv < Vmin)
-	      vv += vperiod;
-	  else
-	    {
-	      while (vv >= Vmin)
-		vv -= vperiod;
-	      vv += vperiod;
-	    }
-	}
+      aP.SetY(myVmin - 100.0*aS.VResolution(aMaxTol));
     }
+    else if(Precision::IsInfinite(myVmin))
+    {
+      aP.SetY(myVmax + 100.0*aS.VResolution(aMaxTol));
+    }
+  }
+  else
+  {
+    aP.SetCoord(0.5*(myUmax + myUmin),
+                    (myVmin - Max(aDeltaV + 2.0*aS.VResolution(aMaxTol), 1.0)));
 
-  for (;;)
+    //In order to avoid work with infinite-located curves (e.g. in
+    //half-spaces)
+    if(Precision::IsInfinite(myUmax) && Precision::IsInfinite(myUmin))
     {
-      dedans = 1;
-      gp_Pnt2d Puv(u,v);
-      
-      if(TabOrien(1)!=-1) { 
-	for(Standard_Integer n=1; n<=nbtabclass; n++) { 
-	  Standard_Integer cur = ((CSLib_Class2d *)TabClass(n))->SiDans(Puv);
-	  if(cur==1) { 
-	    if(TabOrien(n)==0) { 
-	      dedans = -1; 
-	      break;
-	    }
-	  }
-	  else if(cur==-1) { 
-	    if(TabOrien(n)==1) {  
-	      dedans = -1; 
-	      break;
-	    }
-	  }
-	  else { 
-	    dedans = 0;
-	    break;
-	  }
-	}
-	if(dedans==0) { 
-	  BRepClass_FaceClassifier aClassifier;
-	  Standard_Real m_Toluv = (Toluv > 4.0) ? 4.0 : Toluv;
-	  //aClassifier.Perform(Face,Puv,Toluv);
-	  aClassifier.Perform(Face,Puv,m_Toluv);
-	  aStatus = aClassifier.State();
-	}
-	if(dedans == 1) { 
-	  aStatus = TopAbs_IN;
-	}
-	if(dedans == -1) {
-	  aStatus = TopAbs_OUT;
-	}
-      }
-      else {  //-- TabOrien(1)=-1    False Wire
-	BRepClass_FaceClassifier aClassifier;
-	aClassifier.Perform(Face,Puv,Toluv);
-	aStatus = aClassifier.State();
-      }
+      aP.SetX(0.0);
+    }
+    else if(Precision::IsInfinite(myUmax))
+    {
+      aP.SetX(myUmin - 100.0*aS.UResolution(aMaxTol));
+    }
+    else if(Precision::IsInfinite(myUmin))
+    {
+      aP.SetX(myUmax + 100.0*aS.UResolution(aMaxTol));
+    }
+  }
 
-      if (!RecadreOnPeriodic || (!IsUPer && !IsVPer))
-	return aStatus;
-      if (aStatus == TopAbs_IN || aStatus == TopAbs_ON)
-	return aStatus;
+#ifdef BREPTOPADAPTOR_FCLASS2D_DEBUG
+  std::cout << "BRepTopAdaptor_FClass2d::PerformInfinitePoint: point " << 
+                                            aP.X() << " " << aP.Y() << std::endl;
+#endif
 
-      if (!urecadre)
-	{
-	  u = uu;
-	  urecadre = Standard_True;
-	}
-      else
-	if (IsUPer)
-	  u += uperiod;
-      if (u > Umax || !IsUPer)
-	{
-	  if (!vrecadre)
-	    {
-	      v = vv;
-	      vrecadre = Standard_True;
-	    }
-	  else
-	    if (IsVPer)
-	      v += vperiod;
-
-	  u = uu;
-
-	  if (v > Vmax || !IsVPer)
-	    return aStatus;
-	}
-    } //for (;;)
+  return (Perform(aP, Standard_False));
 }
 
-TopAbs_State BRepTopAdaptor_FClass2d::TestOnRestriction(const gp_Pnt2d& _Puv,
-							const Standard_Real Tol,
-							const Standard_Boolean RecadreOnPeriodic) const
+//=======================================================================
+//function : Perform
+//purpose  : 
+//=======================================================================
+TopAbs_State 
+        BRepTopAdaptor_FClass2d::Perform(const gp_Pnt2d& theP2D,
+                                         const Standard_Boolean theIsReqToAdjust) const
 { 
-#if LBRCOMPT 
-  STAT.NbConstrShape++;
-#endif
-  
-  Standard_Integer dedans;
-  Standard_Integer nbtabclass = TabClass.Length();
-  
-  if(nbtabclass==0) { 
-    return(TopAbs_IN);
+  const Standard_Integer aNbTabClass = myTabClass.Length();
+  if(aNbTabClass == 0)
+  {
+    return TopAbs_IN;
   }
-  
-  //-- U1 is the First Param and U2 in this case is U1+Period
-  Standard_Real u=_Puv.X();
-  Standard_Real v=_Puv.Y();
-  Standard_Real uu = u, vv = v;
-  
-  Handle(BRepAdaptor_HSurface) surf = new BRepAdaptor_HSurface();
-  surf->ChangeSurface().Initialize( Face, Standard_False );
-  const Standard_Boolean IsUPer  = surf->IsUPeriodic();
-  const Standard_Boolean IsVPer  = surf->IsVPeriodic();
-  const Standard_Real    uperiod = IsUPer ? surf->UPeriod() : 0.0;
-  const Standard_Real    vperiod = IsVPer ? surf->VPeriod() : 0.0;
+
+  Standard_Real aU = theP2D.X();
+  Standard_Real aV = theP2D.Y();
+  Standard_Real aUprev = aU;
+  Standard_Real aVprev = aV;
   TopAbs_State aStatus = TopAbs_UNKNOWN;
-  Standard_Boolean urecadre = Standard_False, vrecadre = Standard_False;
-  
-  if (RecadreOnPeriodic)
+
+  const BRepAdaptor_Surface anAS(myFace, Standard_False);
+
+  const Standard_Boolean IsUPer = anAS.IsUPeriodic();
+  const Standard_Boolean IsVPer = anAS.IsVPeriodic();
+  const Standard_Real    aUperiod = IsUPer ? anAS.UPeriod() : 0.0;
+  const Standard_Real    aVperiod = IsVPer ? anAS.VPeriod() : 0.0;
+
+  Standard_Boolean isUAdjusted = Standard_False, 
+                   isVAdjusted = Standard_False;
+  Standard_Integer aTmpStatus = 1;
+  //
+  if (theIsReqToAdjust) {
+    Standard_Real aDU, aDV;
+    if (IsUPer) {
+      GeomInt::AdjustPeriodic(aUprev, myUmin, myUmax, aUperiod, aUprev, aDU);
+    }// if (IsUPer) {
+    //
+    if (IsVPer) {
+      GeomInt::AdjustPeriodic(aVprev, myVmin, myVmax, aVperiod, aVprev, aDV);
+    }//if (IsVPer) {
+  }
+  //
+  for (;;) {
+    aTmpStatus = 1;
+    gp_Pnt2d aPuv(aU, aV);
+
+#ifdef BREPTOPADAPTOR_FCLASS2D_CheckPolygon
+    const Standard_Boolean hasToUseClassifier = Standard_False;
+#else
+    Standard_Boolean hasToUseClassifier = (myTabOrien(1) == -1);
+#endif
+
+    if(!hasToUseClassifier)
+    {
+      for(Standard_Integer aN = 1; aN <= aNbTabClass; aN++)
+      {
+        const Standard_Integer aPolyStatus = myTabClass(aN)->Classify(aPuv);
+        const Standard_Integer aTabOri = myTabOrien(aN);
+        if(aPolyStatus == 1)
+        {
+          if(aTabOri == 0)
+          {
+            aTmpStatus = -1;
+            break;
+          }
+        }
+        else if(aPolyStatus == -1)
+        {
+          if(aTabOri == 1)
+          {
+            aTmpStatus = -1;
+            break;
+          }
+        }
+        else {
+          aTmpStatus = 0;
+          break;
+        }
+      } // for(n=1; n<=nbtabclass; n++)
+
+      if(aTmpStatus == 0)
+      {
+#if BREPTOPADAPTOR_FCLASS2D_CheckPolygon
+        aStatus = TopAbs_ON;
+#else
+        hasToUseClassifier = Standard_True;
+#endif
+      }
+      else
+      {
+        aStatus = (aTmpStatus == 1) ? TopAbs_IN : TopAbs_OUT;
+      }
+    } // if(TabOrien(1)!=-1) {
+    //compute state of the point using face classifier
+    if(hasToUseClassifier)
     {
-      if (IsUPer)
-	{
-	  if (uu < Umin)
-	    while (uu < Umin)
-	      uu += uperiod;
-	  else
-	    {
-	      while (uu >= Umin)
-		uu -= uperiod;
-	      uu += uperiod;
-	    }
-	}
-      if (IsVPer)
-	{
-	  if (vv < Vmin)
-	    while (vv < Vmin)
-	      vv += vperiod;
-	  else
-	    {
-	      while (vv >= Vmin)
-		vv -= vperiod;
-	      vv += vperiod;
-	    }
-	}
+      myClassifier.Perform(myFace, aPuv, myTol3D);
+      aStatus = myClassifier.State();
     }
-  
-  for (;;)
+
+    if (!theIsReqToAdjust || (!IsUPer && !IsVPer))
+      return aStatus;
+    
+    if (aStatus == TopAbs_IN || aStatus == TopAbs_ON)
+      return aStatus;
+    
+    if(!isUAdjusted)
     {
-      dedans = 1;
-      gp_Pnt2d Puv(u,v);
-      
-      if(TabOrien(1)!=-1) { 
-	for(Standard_Integer n=1; n<=nbtabclass; n++) { 
-	  Standard_Integer cur = ((CSLib_Class2d *)TabClass(n))->SiDans_OnMode(Puv,Tol);
-	  if(cur==1) { 
-	    if(TabOrien(n)==0) { 
-	      dedans = -1; 
-	      break;
-	    }
-	  }
-	  else if(cur==-1) { 
-	    if(TabOrien(n)==1) {  
-	      dedans = -1; 
-	      break;
-	    }
-	  }
-	  else { 
-	    dedans = 0;
-	    break;
-	  }
-	}
-	if(dedans==0) {
-	  aStatus = TopAbs_ON;
-	}
-	if(dedans == 1) {
-	  aStatus = TopAbs_IN;
-	}
-	if(dedans == -1) {
-	  aStatus = TopAbs_OUT;
-	}
+      aU = aUprev;
+      isUAdjusted = Standard_True;
+    }
+    else {
+      if (IsUPer){
+        aU += aUperiod;
       }
-      else {  //-- TabOrien(1)=-1    False Wire
-	BRepClass_FaceClassifier aClassifier;
-	aClassifier.Perform(Face,Puv,Tol);
-	aStatus = aClassifier.State();
+    }
+
+    if(aU > myUmax || !IsUPer)
+    {
+      if(!isVAdjusted)
+      {
+        aV = aVprev;
+        isVAdjusted = Standard_True;
       }
+      else {
+        if (IsVPer){
+          aV += aVperiod;
+        }
+      }
+
+      aU = aUprev;
       
-      if (!RecadreOnPeriodic || (!IsUPer && !IsVPer))
-	return aStatus;
-      if (aStatus == TopAbs_IN || aStatus == TopAbs_ON)
-	return aStatus;
-      
-      if (!urecadre)
-	{
-	  u = uu;
-	  urecadre = Standard_True;
-	}
-      else
-	if (IsUPer)
-	  u += uperiod;
-      if (u > Umax || !IsUPer)
-	{
-	  if (!vrecadre)
-	    {
-	      v = vv;
-	      vrecadre = Standard_True;
-	    }
-	  else
-	    if (IsVPer)
-	      v += vperiod;
-	  
-	  u = uu;
-	  
-	  if (v > Vmax || !IsVPer)
-	    return aStatus;
-	}
-    } //for (;;)
+      if(aV > myVmax || !IsVPer)
+      {
+        return aStatus;
+      }
+    }
+  } //while (1)
 }
 
+//=======================================================================
+//function : TestOnRestriction
+//purpose  : 
+//=======================================================================
+TopAbs_State 
+BRepTopAdaptor_FClass2d::TestOnRestriction(const gp_Pnt2d& theP2D,
+                                           const Standard_Real theTol3D,
+                                           const Standard_Boolean theIsReqToAdjust) const
+{ 
+  const Standard_Integer aNbTabClass = myTabClass.Length();
+  if(aNbTabClass == 0)
+  {
+    return TopAbs_IN;
+  }
+
+  Standard_Real aU = theP2D.X();
+  Standard_Real aV = theP2D.Y();
+  Standard_Real aUprev = aU;
+  Standard_Real aVprev = aV;
+  TopAbs_State aStatus = TopAbs_UNKNOWN;
+
+  const BRepAdaptor_Surface anAS(myFace, Standard_False);
+  const Standard_Real aURes = anAS.UResolution(theTol3D),
+                      aVRes = anAS.VResolution(theTol3D);
+
+  const Standard_Boolean IsUPer = anAS.IsUPeriodic();
+  const Standard_Boolean IsVPer = anAS.IsVPeriodic();
+  const Standard_Real    aUperiod = IsUPer ? anAS.UPeriod() : 0.0;
+  const Standard_Real    aVperiod = IsVPer ? anAS.VPeriod() : 0.0;
 
-void BRepTopAdaptor_FClass2d::Destroy() { 
-#if LBRCOMPT
-  STAT.NbDestroy++;
+  Standard_Boolean isUAdjusted = Standard_False,
+    isVAdjusted = Standard_False;
+  Standard_Integer aTmpStatus = 1;
+  //
+  if(theIsReqToAdjust)
+  {
+    Standard_Real aDU, aDV;
+    if(IsUPer)
+    {
+      GeomInt::AdjustPeriodic(aUprev, myUmin, myUmax, aUperiod, aUprev, aDU);
+    }// if (IsUPer) {
+    //
+    if(IsVPer)
+    {
+      GeomInt::AdjustPeriodic(aVprev, myVmin, myVmax, aVperiod, aVprev, aDV);
+    }//if (IsVPer) {
+  }
+  //
+  for(;;)
+  {
+    aTmpStatus = 1;
+    gp_Pnt2d aPuv(aU, aV);
+
+#ifdef BREPTOPADAPTOR_FCLASS2D_CheckPolygon
+    const Standard_Boolean bUseClassifier = Standard_False;
+#else
+    Standard_Boolean hasToUseClassifier = (myTabOrien(1) == -1);
 #endif
-  
-  Standard_Integer nbtabclass = TabClass.Length(); 
-  for(Standard_Integer d=1; d<=nbtabclass;d++) {
-    if(TabClass(d)) { 
-      delete ((CSLib_Class2d *)TabClass(d));
-      TabClass(d)=NULL;
+
+    if(!hasToUseClassifier)
+    {
+      for(Standard_Integer aN = 1; aN <= aNbTabClass; aN++)
+      {
+        const Standard_Integer aPolyStatus = myTabClass(aN)->Classify(aPuv, aURes, aVRes);
+        const Standard_Integer aTabOri = myTabOrien(aN);
+        if(aPolyStatus == 1)
+        {
+          if(aTabOri == 0)
+          {
+            aTmpStatus = -1;
+            break;
+          }
+        }
+        else if(aPolyStatus == -1)
+        {
+          if(aTabOri == 1)
+          {
+            aTmpStatus = -1;
+            break;
+          }
+        }
+        else
+        {
+          aTmpStatus = 0;
+          break;
+        }
+      } // for(n=1; n<=nbtabclass; n++)
+
+      if(aTmpStatus == 0)
+      {
+#if BREPTOPADAPTOR_FCLASS2D_CheckPolygon
+        aStatus = TopAbs_ON;
+#else
+        hasToUseClassifier = Standard_True;
+#endif
+      }
+      else
+      {
+        aStatus = (aTmpStatus == 1) ? TopAbs_IN : TopAbs_OUT;
+      }
+    } // if(TabOrien(1)!=-1) {
+    //compute state of the point using face classifier
+    if(hasToUseClassifier)
+    {
+      myClassifier.Perform(myFace, aPuv, theTol3D);
+      aStatus = myClassifier.State();
     }
-  }
-}
 
+    if(!theIsReqToAdjust || (!IsUPer && !IsVPer))
+      return aStatus;
 
+    if(aStatus == TopAbs_IN || aStatus == TopAbs_ON)
+      return aStatus;
 
-#include <Standard_ConstructionError.hxx>
+    if(!isUAdjusted)
+    {
+      aU = aUprev;
+      isUAdjusted = Standard_True;
+    }
+    else
+    {
+      if(IsUPer)
+      {
+        aU += aUperiod;
+      }
+    }
 
+    if(aU > myUmax || !IsUPer)
+    {
+      if(!isVAdjusted)
+      {
+        aV = aVprev;
+        isVAdjusted = Standard_True;
+      }
+      else
+      {
+        if(IsVPer)
+        {
+          aV += aVperiod;
+        }
+      }
 
-//const BRepTopAdaptor_FClass2d &  BRepTopAdaptor_FClass2d::Copy(const BRepTopAdaptor_FClass2d& Other) const { 
-const BRepTopAdaptor_FClass2d &  BRepTopAdaptor_FClass2d::Copy(const BRepTopAdaptor_FClass2d& ) const { 
-#ifdef OCCT_DEBUG
-  cerr<<"Copy not allowed in BRepTopAdaptor_FClass2d"<<endl;
-#endif
-  throw Standard_ConstructionError();
+      aU = aUprev;
+
+      if(aV > myVmax || !IsVPer)
+      {
+        return aStatus;
+      }
+    }
+  } //while (1)
 }
+
+//=======================================================================
+//function : Destroy
+//purpose  : 
+//=======================================================================
+void BRepTopAdaptor_FClass2d::Destroy()
+{
+  Standard_Integer nbtabclass = myTabClass.Length();
+  for (Standard_Integer d = 1; d <= nbtabclass; d++)
+  {
+    if(myTabClass(d))
+    {
+      delete myTabClass(d);
+    }
+  }
+
+  myTabClass.Clear();
+  myTabOrien.Clear();
+}
\ No newline at end of file
diff --git a/src/BRepTopAdaptor/BRepTopAdaptor_FClass2d.hxx b/src/BRepTopAdaptor/BRepTopAdaptor_FClass2d.hxx
index 0dc6dce..a7a240a 100644
--- a/src/BRepTopAdaptor/BRepTopAdaptor_FClass2d.hxx
+++ b/src/BRepTopAdaptor/BRepTopAdaptor_FClass2d.hxx
@@ -17,20 +17,17 @@
 #ifndef _BRepTopAdaptor_FClass2d_HeaderFile
 #define _BRepTopAdaptor_FClass2d_HeaderFile
 
-#include <Standard.hxx>
-#include <Standard_DefineAlloc.hxx>
-#include <Standard_Handle.hxx>
-
-#include <BRepTopAdaptor_SeqOfPtr.hxx>
-#include <TColStd_SequenceOfInteger.hxx>
-#include <Standard_Real.hxx>
+#include <BRepClass_FaceClassifier.hxx>
+#include <NCollection_Sequence.hxx>
 #include <TopoDS_Face.hxx>
-#include <TopAbs_State.hxx>
-#include <Standard_Boolean.hxx>
-class TopoDS_Face;
-class gp_Pnt2d;
-
+class CSLib_Class2d;
 
+//! Checks the position of some 2D-point relatively 
+//! to the face.
+//! Returns status ON if the point is in the at least of one
+//! edge of the face.
+//! Returns status IN if the point is included to the face.
+//! Otherwise, returns status OUT.
 
 class BRepTopAdaptor_FClass2d 
 {
@@ -38,55 +35,66 @@ public:
 
   DEFINE_STANDARD_ALLOC
 
+  //! Empty constructor
+  Standard_EXPORT BRepTopAdaptor_FClass2d();
+
+  //! Constructs algorithm by theFace and the 3D-tolerance <theTol3D>
+  Standard_EXPORT BRepTopAdaptor_FClass2d(const TopoDS_Face& theFace,
+                                          const Standard_Real theTol3D);
   
-  Standard_EXPORT BRepTopAdaptor_FClass2d(const TopoDS_Face& F, const Standard_Real Tol);
-  
+  //! Initializes algorithm by theFace and the 3D-tolerance <theTol3D>
+  Standard_EXPORT void Init(const TopoDS_Face& theFace,
+                            const Standard_Real theTol3D);
+
+  //! Classifies an infinite 2d point relatively of the Face.
   Standard_EXPORT TopAbs_State PerformInfinitePoint() const;
   
-  Standard_EXPORT TopAbs_State Perform (const gp_Pnt2d& Puv, const Standard_Boolean RecadreOnPeriodic = Standard_True) const;
+  //! Returns state of the 2d point theP2D.
+  //! If theIsReqToAdjust==TRUE the point will be adjusted
+  //! to period for a periodical surface before classification.
+  Standard_EXPORT TopAbs_State
+    Perform(const gp_Pnt2d& theP2D,
+            const Standard_Boolean theIsReqToAdjust = Standard_True) const;
   
+  //! Destructor
   Standard_EXPORT void Destroy();
-~BRepTopAdaptor_FClass2d()
-{
-  Destroy();
-}
-  
-  Standard_EXPORT const BRepTopAdaptor_FClass2d& Copy (const BRepTopAdaptor_FClass2d& Other) const;
-const BRepTopAdaptor_FClass2d& operator= (const BRepTopAdaptor_FClass2d& Other) const
-{
-  return Copy(Other);
-}
+  ~BRepTopAdaptor_FClass2d()
+  {
+    Destroy();
+  }
   
-  //! Test a point with +- an offset (Tol) and returns
-  //! On if some points are OUT an some are IN
-  //! (Caution: Internal use . see the code for more details)
-  Standard_EXPORT TopAbs_State TestOnRestriction (const gp_Pnt2d& Puv, const Standard_Real Tol, const Standard_Boolean RecadreOnPeriodic = Standard_True) const;
-
-
+  //! Classifies theP2D using 3D-tolerance theTol3D.
+  //! If theIsReqToAdjust==TRUE the point will be adjusted
+  //! to period for a periodical surface before classification.
+  Standard_EXPORT TopAbs_State
+    TestOnRestriction(const gp_Pnt2d& theP2D,
+                      const Standard_Real theTol3D,
+                      const Standard_Boolean theIsReqToAdjust = Standard_True) const;
+
+  //! Returns TRUE if material of the Face
+  //! outside of its outer wire. 
+  Standard_Boolean IsHole() const
+  {
+    return (PerformInfinitePoint() == TopAbs_IN);
+  }
 
 
 protected:
-
+  const BRepTopAdaptor_FClass2d& operator= (const BRepTopAdaptor_FClass2d&) const;
 
 
 
 
 private:
-
-
-
-  BRepTopAdaptor_SeqOfPtr TabClass;
-  TColStd_SequenceOfInteger TabOrien;
-  Standard_Real Toluv;
-  TopoDS_Face Face;
-  Standard_Real U1;
-  Standard_Real V1;
-  Standard_Real U2;
-  Standard_Real V2;
-  Standard_Real Umin;
-  Standard_Real Umax;
-  Standard_Real Vmin;
-  Standard_Real Vmax;
+  mutable BRepClass_FaceClassifier myClassifier;
+  NCollection_Sequence<CSLib_Class2d*> myTabClass;
+  NCollection_Sequence<Standard_Integer> myTabOrien;
+  TopoDS_Face myFace;
+  Standard_Real myTol3D;
+  Standard_Real myUmin;
+  Standard_Real myVmin;
+  Standard_Real myUmax;
+  Standard_Real myVmax;
 
 
 };
diff --git a/src/BRepTopAdaptor/BRepTopAdaptor_Tool.cxx b/src/BRepTopAdaptor/BRepTopAdaptor_Tool.cxx
index 80b7d14..0c0c82c 100644
--- a/src/BRepTopAdaptor/BRepTopAdaptor_Tool.cxx
+++ b/src/BRepTopAdaptor/BRepTopAdaptor_Tool.cxx
@@ -96,9 +96,6 @@ void BRepTopAdaptor_Tool::SetTopolTool(const Handle(BRepTopAdaptor_TopolTool)& T
 }
 
 void BRepTopAdaptor_Tool::Destroy() { 
-  int i;
-  i=0;
-  i++;
   
 }
 
diff --git a/src/BRepTopAdaptor/BRepTopAdaptor_TopolTool.cxx b/src/BRepTopAdaptor/BRepTopAdaptor_TopolTool.cxx
index 0b608df..121bcb2 100644
--- a/src/BRepTopAdaptor/BRepTopAdaptor_TopolTool.cxx
+++ b/src/BRepTopAdaptor/BRepTopAdaptor_TopolTool.cxx
@@ -84,7 +84,7 @@ static
   s_wnt.Orientation(TopAbs_FORWARD);
   myFace = TopoDS::Face(s_wnt);
   if(myFClass2d != NULL) { 
-    delete (BRepTopAdaptor_FClass2d *)myFClass2d;
+    delete myFClass2d;
   } 
   myFClass2d = NULL;
   myNbSamplesU=-1;
@@ -188,30 +188,33 @@ static
 //function : Classify
 //purpose  : 
 //=======================================================================
-  TopAbs_State BRepTopAdaptor_TopolTool::Classify(const gp_Pnt2d& P,
-						  const Standard_Real Tol,
-						  const Standard_Boolean RecadreOnPeriodic)
+TopAbs_State BRepTopAdaptor_TopolTool::Classify(const gp_Pnt2d& P,
+                                                const Standard_Real theTol3D,
+                                                const Standard_Boolean theIsReqToAdjust)
 {
   if(myFace.IsNull())
     return TopAbs_UNKNOWN;
   if(myFClass2d == NULL) { 
-    myFClass2d = (void *) new BRepTopAdaptor_FClass2d(myFace,Tol);
+    myFClass2d = new BRepTopAdaptor_FClass2d(myFace, theTol3D);
   } 
-  return(((BRepTopAdaptor_FClass2d *)myFClass2d)->Perform(P,RecadreOnPeriodic));
+
+  const TopAbs_State aState = (myFClass2d->Perform(P,theIsReqToAdjust));
+  return aState;
 }
 
 //=======================================================================
 //function : IsThePointOn
 //purpose  : 
 //=======================================================================
-  Standard_Boolean BRepTopAdaptor_TopolTool::IsThePointOn(const gp_Pnt2d& P,
-							  const Standard_Real Tol,
-							  const Standard_Boolean RecadreOnPeriodic)
+Standard_Boolean
+    BRepTopAdaptor_TopolTool::IsThePointOn(const gp_Pnt2d& P,
+                                           const Standard_Real theTol3D,
+                                           const Standard_Boolean theIsReqToAdjust)
 {
   if(myFClass2d == NULL) { 
-    myFClass2d = (void *) new BRepTopAdaptor_FClass2d(myFace,Tol);
+    myFClass2d = new BRepTopAdaptor_FClass2d(myFace, theTol3D);
   } 
-  return(TopAbs_ON==((BRepTopAdaptor_FClass2d *)myFClass2d)->TestOnRestriction(P,Tol,RecadreOnPeriodic));
+  return(TopAbs_ON == myFClass2d->TestOnRestriction(P, theTol3D, theIsReqToAdjust));
 }
 
 //=======================================================================
@@ -221,7 +224,7 @@ static
   void BRepTopAdaptor_TopolTool::Destroy() 
 { 
   if(myFClass2d != NULL) { 
-    delete (BRepTopAdaptor_FClass2d *)myFClass2d;
+    delete myFClass2d;
     myFClass2d=NULL;
   }
 }
diff --git a/src/BRepTopAdaptor/BRepTopAdaptor_TopolTool.hxx b/src/BRepTopAdaptor/BRepTopAdaptor_TopolTool.hxx
index e95e588..592295c 100644
--- a/src/BRepTopAdaptor/BRepTopAdaptor_TopolTool.hxx
+++ b/src/BRepTopAdaptor/BRepTopAdaptor_TopolTool.hxx
@@ -32,6 +32,7 @@
 #include <TopAbs_Orientation.hxx>
 #include <Standard_Integer.hxx>
 class BRepAdaptor_HCurve2d;
+class BRepTopAdaptor_FClass2d;
 class Standard_DomainError;
 class Adaptor3d_HSurface;
 class Adaptor2d_HCurve2d;
@@ -78,10 +79,25 @@ public:
   
   Standard_EXPORT virtual void NextVertex() Standard_OVERRIDE;
   
-  Standard_EXPORT virtual TopAbs_State Classify (const gp_Pnt2d& P2d, const Standard_Real Tol, const Standard_Boolean RecadreOnPeriodic = Standard_True) Standard_OVERRIDE;
-  
-  //! see the code for specifications)
-  Standard_EXPORT virtual Standard_Boolean IsThePointOn (const gp_Pnt2d& P2d, const Standard_Real Tol, const Standard_Boolean RecadreOnPeriodic = Standard_True) Standard_OVERRIDE;
+  //! Classifies theP2d relatively to the domain of myS.
+  //! theTol3D is the 3D-tolerance (is used for check ON-status).
+  //! If theIsReqToAdjust == TRUE then the coordinates of theP2d
+  //! will be inscribed (if it is possible) in the UV-bounds of myFace.
+  Standard_EXPORT virtual
+      TopAbs_State Classify(const gp_Pnt2d& theP2d, 
+                            const Standard_Real theTol3D,
+                            const Standard_Boolean theIsReqToAdjust = 
+                                                      Standard_True) Standard_OVERRIDE;
+  
+  //! Returns TRUE if theP is in the some edge of myFace with given
+  //! 3D-tolerance theTol3D.
+  //! If theIsReqToAdjust == TRUE then the coordinates of theP2d
+  //! will be inscribed (if it is possible) in the UV-bounds of myFace.
+  Standard_EXPORT virtual Standard_Boolean
+          IsThePointOn(const gp_Pnt2d& P2d,
+                       const Standard_Real theTol3D,
+                       const Standard_Boolean 
+                                theIsReqToAdjust = Standard_True) Standard_OVERRIDE;
   
   //! If the function returns the orientation of the arc.
   //! If the orientation is FORWARD or REVERSED, the arc is
@@ -131,7 +147,11 @@ public:
   
   Standard_EXPORT virtual Standard_Boolean DomainIsInfinite() Standard_OVERRIDE;
 
-
+  //! Returns face
+  const TopoDS_Face& GetFace() const
+  {
+    return myFace;
+  }
 
   DEFINE_STANDARD_RTTIEXT(BRepTopAdaptor_TopolTool,Adaptor3d_TopolTool)
 
@@ -145,7 +165,7 @@ private:
 
   TopExp_Explorer myVIterator;
   TopoDS_Face myFace;
-  Standard_Address myFClass2d;
+  BRepTopAdaptor_FClass2d *myFClass2d;
   Handle(BRepAdaptor_HCurve2d) myCurve;
   TColStd_ListOfTransient myCurves;
   TColStd_ListIteratorOfListOfTransient myCIterator;
diff --git a/src/Blend/Blend_CSWalking_1.gxx b/src/Blend/Blend_CSWalking_1.gxx
index e86ee57..2d132ca 100644
--- a/src/Blend/Blend_CSWalking_1.gxx
+++ b/src/Blend/Blend_CSWalking_1.gxx
@@ -18,7 +18,7 @@ Blend_CSWalking::Blend_CSWalking(const TheCurve& Curv,
        done(Standard_False),surf(Surf),
        curv(Curv)
 {
-  domain = Domain;
+  myDomain = Domain;
 }
 
 
@@ -30,7 +30,7 @@ void Blend_CSWalking::Perform(Blend_CSFunction& Func,
 			      const Standard_Real MaxStep,
 			      const Standard_Real TolGuide,
 			      const math_Vector& ParDep,
-			      const Standard_Real Tolesp,
+			      const Standard_Real the3DTolEsp,
 			      const Standard_Real Fleche,
 			      const Standard_Boolean Appro)
 {
@@ -40,7 +40,7 @@ void Blend_CSWalking::Perform(Blend_CSFunction& Func,
   comptra = Standard_False;
   line = new TheLine ();
   Standard_Integer Nbvar = Func.NbVariables();
-  tolesp = Abs(Tolesp);
+  my3DTolEsp = Abs(the3DTolEsp);
   tolgui = Abs(TolGuide);
   fleche = Abs(Fleche);
   rebrou = Standard_False;
@@ -67,10 +67,10 @@ void Blend_CSWalking::Perform(Blend_CSFunction& Func,
 
     TopAbs_State situ;
 //    math_Vector tolerance(1,3),infbound(1,3),supbound(1,3);
-    math_Vector tolerance(1,Nbvar),infbound(1,Nbvar),supbound(1,Nbvar);
-    Func.GetTolerance(tolerance,tolesp);
+    math_Vector aVTol2D(1,Nbvar),infbound(1,Nbvar),supbound(1,Nbvar);
+    Func.GetTolerance(aVTol2D, my3DTolEsp);
     Func.GetBounds(infbound,supbound);
-    math_FunctionSetRoot rsnld(Func,tolerance,30);
+    math_FunctionSetRoot rsnld(Func,aVTol2D,30);
 
     rsnld.Perform(Func,ParDep,infbound,supbound);
     
@@ -79,16 +79,7 @@ void Blend_CSWalking::Perform(Blend_CSFunction& Func,
     }
     rsnld.Root(sol);
 
-//    situ1 = TheTopolTool::Classify(surf1,gp_Pnt2d(sol(1),sol(2)),
-//				   Max(tolerance(1),tolerance(2)));
-//    situ2 = TheTopolTool::Classify(surf2,gp_Pnt2d(sol(3),sol(4)),
-//				   Max(tolerance(3),tolerance(4)));
-/*
-    situ = domain->Classify(gp_Pnt2d(sol(1),sol(2)),
-			      Min(tolerance(1),tolerance(2)));
-*/
-    situ = domain->Classify(Func.Pnt2d(),
-			    Min(tolerance(1),tolerance(2)));
+    situ = myDomain->Classify(Func.Pnt2d(), my3DTolEsp);
 
     if (situ != TopAbs_IN ) {
       return;
@@ -115,8 +106,8 @@ void Blend_CSWalking::Perform(Blend_CSFunction& Func,
   Standard_Real U,V,W;
   previousP.ParametersOnS(U,V);
   W = previousP.ParameterOnC();
-  TheExtremity P1(previousP.PointOnS(),U,V,previousP.Parameter(),tolesp);
-  TheExtremity P2(previousP.PointOnC(),W,previousP.Parameter(),tolesp);
+  TheExtremity P1(previousP.PointOnS(), U, V, previousP.Parameter(), my3DTolEsp);
+  TheExtremity P2(previousP.PointOnC(), W, previousP.Parameter(), my3DTolEsp);
   if (sens>0.) {
     line->SetStartPoints(P1,P2);
   }
diff --git a/src/Blend/Blend_CSWalking_2.gxx b/src/Blend/Blend_CSWalking_2.gxx
index fba4785..3f8574a 100644
--- a/src/Blend/Blend_CSWalking_2.gxx
+++ b/src/Blend/Blend_CSWalking_2.gxx
@@ -39,7 +39,7 @@ Blend_Status Blend_CSWalking::TestArret(Blend_CSFunction& Function,
   Blend_Status State1,State2;
   IntSurf_TypeTrans tras = IntSurf_Undecided;
 
-  if (Function.IsSolution(Sol,tolesp)) {
+  if (Function.IsSolution(Sol, my3DTolEsp)) {
 
     pt1  = Function.PointOnS();
     pt2  = Function.PointOnC();
@@ -176,15 +176,15 @@ Blend_Status Blend_CSWalking::CheckDeflectionOnSurf
 
   prevP = previousP.PointOnS();
   prevTg = previousP.TangentOnS();
-  tolu = TheSurfaceTool::UResolution(surf,tolesp);
-  tolv = TheSurfaceTool::VResolution(surf,tolesp);
+  tolu = TheSurfaceTool::UResolution(surf, my3DTolEsp);
+  tolv = TheSurfaceTool::VResolution(surf, my3DTolEsp);
 
   gp_Vec Corde(prevP,Psurf);
   Norme = Corde.SquareMagnitude();
   prevNorme = prevTg.SquareMagnitude(); // JAG MODIF 25.04.94
 
 
-  if (Norme <= tolesp*tolesp || prevNorme <= tolesp*tolesp) { // JAG MODIF 25.04.94
+  if (Norme <= my3DTolEsp*my3DTolEsp || prevNorme <= my3DTolEsp*my3DTolEsp) { // JAG MODIF 25.04.94
     // il faudra peut etre  forcer meme point  JAG MODIF 25.04.94
     return Blend_SamePoints;
   }
@@ -275,7 +275,7 @@ Blend_Status Blend_CSWalking::CheckDeflectionOnCurv
 
   prevP = previousP.PointOnC();
   prevTg = previousP.TangentOnC();
-  tolu = TheCurveTool::Resolution(curv,tolesp);
+  tolu = TheCurveTool::Resolution(curv, my3DTolEsp);
 
   gp_Vec Corde(prevP,Pcurv);
   Norme = Corde.SquareMagnitude();
@@ -283,11 +283,11 @@ Blend_Status Blend_CSWalking::CheckDeflectionOnCurv
 
 
 // if (Norme <= tolesp*tolesp || prevNorme <= tolesp*tolesp) { // JAG MODIF 25.04.94
-  if (Norme <= tolesp*tolesp) { // le 95.01.10
+  if (Norme <= my3DTolEsp*my3DTolEsp) { // le 95.01.10
     // il faudra peut etre  forcer meme point  JAG MODIF 25.04.94
     return Blend_SamePoints;
   }
-  else if (prevNorme > tolesp*tolesp) {
+  else if (prevNorme > my3DTolEsp*my3DTolEsp) {
     Cosi = sens*Corde*prevTg;
     if (Cosi <0.) { // angle 3d>pi/2. --> retour arriere
       return Blend_Backward;
@@ -308,7 +308,7 @@ Blend_Status Blend_CSWalking::CheckDeflectionOnCurv
 
   // Voir s il faut faire le controle sur le signe de prevtg*Tgsurf
 
-  if (Tgcurv.Magnitude() <= tolesp) {
+  if (Tgcurv.SquareMagnitude() <= my3DTolEsp*my3DTolEsp) {
     return Blend_SamePoints; // GROS BOBARD EN ATTENDANT
   }
 
@@ -318,7 +318,7 @@ Blend_Status Blend_CSWalking::CheckDeflectionOnCurv
     return Blend_StepTooLarge;
   }
 
-  if (prevNorme > tolesp*tolesp) {
+  if (prevNorme > my3DTolEsp*my3DTolEsp) {
 
     // Estimation de la fleche courante
 /*    
diff --git a/src/Blend/Blend_CSWalking_3.gxx b/src/Blend/Blend_CSWalking_3.gxx
index 5f623b8..291aad2 100644
--- a/src/Blend/Blend_CSWalking_3.gxx
+++ b/src/Blend/Blend_CSWalking_3.gxx
@@ -205,8 +205,8 @@ void Blend_CSWalking::MakeExtremity(TheExtremity& Extrem,
 
 //  Extrem.SetValue(previousP.PointOnS(),sol(1),sol(2),tolesp);
   previousP.ParametersOnS(U,V);
-  Extrem.SetValue(previousP.PointOnS(),U,V,previousP.Parameter(),tolesp);
-  Iter = domain;
+  Extrem.SetValue(previousP.PointOnS(), U, V, previousP.Parameter(), my3DTolEsp);
+  Iter = myDomain;
 
 
   Iter->Init();
diff --git a/src/Blend/Blend_CSWalking_4.gxx b/src/Blend/Blend_CSWalking_4.gxx
index ce7ed90..7598972 100644
--- a/src/Blend/Blend_CSWalking_4.gxx
+++ b/src/Blend/Blend_CSWalking_4.gxx
@@ -32,7 +32,7 @@ void Blend_CSWalking::InternalPerform(Blend_CSFunction& Func,
   gp_Pnt2d p2d;
 //  math_Vector tolerance(1,3),infbound(1,3),supbound(1,3),parinit(1,3);
 //  math_Vector solrst(1,3);
-  math_Vector tolerance(1,Nbvar),infbound(1,Nbvar),supbound(1,Nbvar),
+  math_Vector aVTol2D(1,Nbvar),infbound(1,Nbvar),supbound(1,Nbvar),
               parinit(1,Nbvar);
   math_Vector solrst(1,Nbvar);
   TheVertex Vtx;
@@ -40,10 +40,10 @@ void Blend_CSWalking::InternalPerform(Blend_CSFunction& Func,
 
   //IntSurf_Transition Tline,Tarc;
 
-  Func.GetTolerance(tolerance,tolesp);
+  Func.GetTolerance(aVTol2D, my3DTolEsp);
   Func.GetBounds(infbound,supbound);
 
-  math_FunctionSetRoot rsnld(Func,tolerance,30);
+  math_FunctionSetRoot rsnld(Func,aVTol2D,30);
   parinit = sol;
 
   param = parprec + sens*stepw;
@@ -64,16 +64,7 @@ void Blend_CSWalking::InternalPerform(Blend_CSFunction& Func,
     else {
       rsnld.Root(sol);
 
-//      situ1 = TheTopolTool::Classify(surf1,gp_Pnt2d(sol(1),sol(2)),
-//				     Max(tolerance(1),tolerance(2)));
-//      situ2 = TheTopolTool::Classify(surf2,gp_Pnt2d(sol(3),sol(4)),
-//				     Max(tolerance(3),tolerance(4)));
-/*
-      situ = domain->Classify(gp_Pnt2d(sol(1),sol(2)),
-			      Min(tolerance(1),tolerance(2)));
-*/
-      situ = domain->Classify(Func.Pnt2d(),
-			      Min(tolerance(1),tolerance(2)));
+      situ = myDomain->Classify(Func.Pnt2d(), my3DTolEsp);
 
       w = Bound;
       recad = Standard_False;
@@ -96,13 +87,13 @@ void Blend_CSWalking::InternalPerform(Blend_CSFunction& Func,
 	  // sol sur surf
 	  State = Blend_OnRst1;
 	  param = w;
-	  domain->Init();
+	  myDomain->Init();
 	  nbarc = 1;
 	  while (nbarc < Index) {
 	    nbarc++;
-	    domain->Next();
+	    myDomain->Next();
 	  }
-	  p2d = TheArcTool::Value(domain->Value(),solrst(1));
+	  p2d = TheArcTool::Value(myDomain->Value(),solrst(1));
 	  sol(1) = p2d.X();
 	  sol(2) = p2d.Y();
 	  sol(3) = solrst(3);
@@ -146,9 +137,9 @@ void Blend_CSWalking::InternalPerform(Blend_CSFunction& Func,
 */
 	  previousP.ParametersOnS(U,V);
 	  Exts.SetValue(previousP.PointOnS(),U,V, 
-			previousP.Parameter(),tolesp);
+                        previousP.Parameter(), my3DTolEsp);
 	  Extc.SetValue(previousP.PointOnC(),previousP.ParameterOnC(),
-			previousP.Parameter(),tolesp);
+                        previousP.Parameter(), my3DTolEsp);
 	  // Indiquer que fin sur Bound.
 	}
 	else {
@@ -171,9 +162,9 @@ void Blend_CSWalking::InternalPerform(Blend_CSFunction& Func,
 */
 	  previousP.ParametersOnS(U,V);
 	  Exts.SetValue(previousP.PointOnS(),U,V,
-			previousP.Parameter(),tolesp);
+                        previousP.Parameter(), my3DTolEsp);
 	  Extc.SetValue(previousP.PointOnC(),previousP.ParameterOnC(),
-			previousP.Parameter(),tolesp);
+                        previousP.Parameter(), my3DTolEsp);
 	  Arrive = Standard_True;
 	  if (line->NbPoints()>=2) {
 	    // Indiquer qu on s arrete en cours de cheminement
@@ -214,9 +205,9 @@ void Blend_CSWalking::InternalPerform(Blend_CSFunction& Func,
 */
 	  previousP.ParametersOnS(U,V);
 	  Exts.SetValue(previousP.PointOnS(),U,V,
-			previousP.Parameter(),tolesp);
+                        previousP.Parameter(), my3DTolEsp);
 	  Extc.SetValue(previousP.PointOnC(),previousP.ParameterOnC(),
-			previousP.Parameter(),tolesp);
+                        previousP.Parameter(), my3DTolEsp);
 	  // Indiquer que fin sur Bound.
 	}
 	else {
@@ -244,7 +235,7 @@ void Blend_CSWalking::InternalPerform(Blend_CSFunction& Func,
 	MakeExtremity(Exts,Index,solrst(1),Isvtx,Vtx);
 //	Extc.SetValue(previousP.PointOnC(),sol(3),tolesp);
 	Extc.SetValue(previousP.PointOnC(),previousP.ParameterOnC(),
-		      previousP.Parameter(),tolesp);
+                      previousP.Parameter(), my3DTolEsp);
 	Arrive = Standard_True;
       }
       break;
@@ -259,9 +250,9 @@ void Blend_CSWalking::InternalPerform(Blend_CSFunction& Func,
 */
 	previousP.ParametersOnS(U,V);
 	Exts.SetValue(previousP.PointOnS(),U,V,
-		      previousP.Parameter(),tolesp);
+                      previousP.Parameter(), my3DTolEsp);
 	Extc.SetValue(previousP.PointOnC(),previousP.ParameterOnC(),
-		      previousP.Parameter(),tolesp);
+                      previousP.Parameter(), my3DTolEsp);
 	Arrive = Standard_True;
       }
       break;
diff --git a/src/Blend/Blend_Walking_1.gxx b/src/Blend/Blend_Walking_1.gxx
index 16373be..5803bd9 100644
--- a/src/Blend/Blend_Walking_1.gxx
+++ b/src/Blend/Blend_Walking_1.gxx
@@ -25,18 +25,18 @@ Blend_Walking::Blend_Walking(const TheSurface& Surf1,
        twistflag1(Standard_False),twistflag2(Standard_False)
 
 {
-  domain1 = Domain1;
-  domain2 = Domain2;
-  recdomain1 = Domain1;
-  recdomain2 = Domain2;
+  myDomain1 = Domain1;
+  myDomain2 = Domain2;
+  myRecDomain1 = Domain1;
+  myRecDomain2 = Domain2;
   hguide = HGuide;
 }
 
 void Blend_Walking::SetDomainsToRecadre(const Handle(TheTopolTool)& Domain1,
 					const Handle(TheTopolTool)& Domain2)
 {
-  recdomain1 = Domain1;
-  recdomain2 = Domain2;
+  myRecDomain1 = Domain1;
+  myRecDomain2 = Domain2;
 }
 
 void Blend_Walking::AddSingularPoint(const Blend_Point& P) 
@@ -64,7 +64,7 @@ void Blend_Walking::Perform(Blend_Function& Func,
 			    const Standard_Real MaxStep,
 			    const Standard_Real TolGuide,
 			    const math_Vector& ParDep,
-			    const Standard_Real Tolesp,
+			    const Standard_Real the3DTolEsp,
 			    const Standard_Real Fleche,
 			    const Standard_Boolean Appro)
 {
@@ -75,7 +75,7 @@ void Blend_Walking::Perform(Blend_Function& Func,
   Standard_Boolean doextremities = 1;
   if(line.IsNull()) line = new TheLine ();
   else {line->Clear();doextremities = 0;}
-  tolesp = Abs(Tolesp);
+  my3DTolEsp = Abs(the3DTolEsp);
   tolgui = Abs(TolGuide);
   fleche = Abs(Fleche);
   rebrou = Standard_False;
@@ -95,10 +95,10 @@ void Blend_Walking::Perform(Blend_Function& Func,
   if (Appro) {
 
     TopAbs_State situ1,situ2;
-    math_Vector tolerance(1,4),infbound(1,4),supbound(1,4);
-    Func.GetTolerance(tolerance,tolesp);
+    math_Vector aVTol2D(1,4),infbound(1,4),supbound(1,4);
+    Func.GetTolerance(aVTol2D, my3DTolEsp);
     Func.GetBounds(infbound,supbound);
-    math_FunctionSetRoot rsnld(Func,tolerance,30);
+    math_FunctionSetRoot rsnld(Func,aVTol2D,30);
 
     rsnld.Perform(Func,ParDep,infbound,supbound);
     
@@ -107,12 +107,22 @@ void Blend_Walking::Perform(Blend_Function& Func,
     }
     rsnld.Root(sol);
 
-    if(clasonS1) situ1 = domain1->Classify(gp_Pnt2d(sol(1),sol(2)),
-					   Min(tolerance(1),tolerance(2)),0);
-    else situ1 = TopAbs_IN;
-    if(clasonS2) situ2 = domain2->Classify(gp_Pnt2d(sol(3),sol(4)),
-					   Min(tolerance(3),tolerance(4)),0);
-    else situ2 = TopAbs_IN;
+    if (clasonS1)
+    {
+      situ1 = myDomain1->Classify(gp_Pnt2d(sol(1), sol(2)), my3DTolEsp, Standard_False);
+    }
+    else
+    {
+      situ1 = TopAbs_IN;
+    }
+    if (clasonS2)
+    {
+      situ2 = myDomain2->Classify(gp_Pnt2d(sol(3), sol(4)), my3DTolEsp, Standard_False);
+    }
+    else
+    {
+      situ2 = TopAbs_IN;
+    }
 
     if (situ1 != TopAbs_IN || situ2 != TopAbs_IN) {
       return;
@@ -143,9 +153,9 @@ void Blend_Walking::Perform(Blend_Function& Func,
 
   if(doextremities){
     TheExtremity ptf1 (previousP.PointOnS1(),
-		       sol(1),sol(2),tolesp);
+                       sol(1),sol(2), my3DTolEsp);
     TheExtremity ptf2 (previousP.PointOnS2(),
-		       sol(3),sol(4),tolesp);
+                       sol(3), sol(4), my3DTolEsp);
     if (!previousP.IsTangencyPoint()) {
       ptf1.SetTangent(previousP.TangentOnS1());
       ptf2.SetTangent(previousP.TangentOnS2());
@@ -168,7 +178,7 @@ void Blend_Walking::Perform(Blend_Function& Func,
 Standard_Boolean Blend_Walking::PerformFirstSection(Blend_Function&     Func,
                                                     const Standard_Real Pdep,
                                                     math_Vector&        ParDep,
-                                                    const Standard_Real Tolesp,
+                                                    const Standard_Real the3DTolEsp,
                                                     const Standard_Real TolGuide,
                                                     TopAbs_State&       Pos1,
                                                     TopAbs_State&       Pos2)
@@ -176,7 +186,7 @@ Standard_Boolean Blend_Walking::PerformFirstSection(Blend_Function&     Func,
   iscomplete = Standard_False;
   comptra = Standard_False;
   line = new TheLine ();
-  tolesp = Abs(Tolesp);
+  my3DTolEsp = Abs(the3DTolEsp);
   tolgui = Abs(TolGuide);
 
   Pos1 = Pos2 = TopAbs_UNKNOWN;
@@ -184,10 +194,10 @@ Standard_Boolean Blend_Walking::PerformFirstSection(Blend_Function&     Func,
   param = Pdep;
   Func.Set(param);
 
-  math_Vector tolerance(1, 4),infbound(1, 4),supbound(1, 4);
-  Func.GetTolerance(tolerance, tolesp);
+  math_Vector aVTol2D(1, 4),infbound(1, 4),supbound(1, 4);
+  Func.GetTolerance(aVTol2D, my3DTolEsp);
   Func.GetBounds(infbound, supbound);
-  math_FunctionSetRoot rsnld(Func, tolerance, 30);
+  math_FunctionSetRoot rsnld(Func, aVTol2D, 30);
 
   rsnld.Perform(Func, ParDep, infbound, supbound);
 
@@ -197,8 +207,10 @@ Standard_Boolean Blend_Walking::PerformFirstSection(Blend_Function&     Func,
   }
   rsnld.Root(sol);
   ParDep = sol;
-  Pos1 = domain1->Classify(gp_Pnt2d(sol(1), sol(2)), Min(tolerance(1), tolerance(2)), 0);
-  Pos2 = domain2->Classify(gp_Pnt2d(sol(3), sol(4)), Min(tolerance(3), tolerance(4)), 0);
+  {
+    Pos1 = myDomain1->Classify(gp_Pnt2d(sol(1), sol(2)), my3DTolEsp, Standard_False);
+    Pos2 = myDomain2->Classify(gp_Pnt2d(sol(3), sol(4)), my3DTolEsp, Standard_False);
+  }
   if (Pos1 != TopAbs_IN || Pos2 != TopAbs_IN)
   {
     return Standard_False;
@@ -220,7 +232,7 @@ Standard_Boolean Blend_Walking::PerformFirstSection (Blend_Function& Func,
                                                      const Standard_Real Pdep,
                                                      const Standard_Real Pmax,
                                                      const math_Vector& ParDep,
-                                                     const Standard_Real Tolesp,
+                                                     const Standard_Real the3DTolEsp,
                                                      const Standard_Real TolGuide,
                                                      const Standard_Boolean RecOnS1,
                                                      const Standard_Boolean RecOnS2,
@@ -235,7 +247,7 @@ Standard_Boolean Blend_Walking::PerformFirstSection (Blend_Function& Func,
   Standard_Real w1, w2, extrapol;
   Standard_Boolean recad1, recad2;
 
-  tolesp = Abs(Tolesp);
+  my3DTolEsp = Abs(the3DTolEsp);
   tolgui = Abs(TolGuide);
   if (Pmax - Pdep >= 0.0)
   {
@@ -252,7 +264,7 @@ Standard_Boolean Blend_Walking::PerformFirstSection (Blend_Function& Func,
   param = Pdep;
   Func.Set(param);
 
-  math_Vector tolerance(1, 4),infbound(1, 4),supbound(1, 4);
+  math_Vector aVTol2D(1, 4),infbound(1, 4),supbound(1, 4);
   math_Vector solrst1(1, 4),solrst2(1, 4);
   TheExtremity Ext1, Ext2;
   Standard_Integer Index1 = 0, Index2 = 0, nbarc;
@@ -262,9 +274,9 @@ Standard_Boolean Blend_Walking::PerformFirstSection (Blend_Function& Func,
   Standard_Real CorrectedU = 0., CorrectedV = 0.;
   gp_Pnt CorrectedPnt;
 
-  Func.GetTolerance(tolerance, tolesp);
+  Func.GetTolerance(aVTol2D, my3DTolEsp);
   Func.GetBounds(infbound, supbound);
-  math_FunctionSetRoot rsnld(Func, tolerance, 30);
+  math_FunctionSetRoot rsnld(Func, aVTol2D, 30);
 
   rsnld.Perform(Func, ParDep, infbound, supbound);
 
@@ -313,14 +325,14 @@ Standard_Boolean Blend_Walking::PerformFirstSection (Blend_Function& Func,
       State = Blend_OnRst1;
       param = w1;
       
-      recdomain1->Init();
+      myRecDomain1->Init();
       nbarc = 1;
       while (nbarc < Index1)
       {
         nbarc++;
-        recdomain1->Next();
+        myRecDomain1->Next();
       }
-      p2d = TheArcTool::Value(recdomain1->Value(), solrst1(1));
+      p2d = TheArcTool::Value(myRecDomain1->Value(), solrst1(1));
       ParSol(1) = p2d.X();
       ParSol(2) = p2d.Y();
       ParSol(3) = solrst1(3);
@@ -333,14 +345,14 @@ Standard_Boolean Blend_Walking::PerformFirstSection (Blend_Function& Func,
       State = Blend_OnRst2;
       param = w2;
       
-      recdomain2->Init();
+      myRecDomain2->Init();
       nbarc = 1;
       while (nbarc < Index2)
       {
         nbarc++;
-        recdomain2->Next();
+        myRecDomain2->Next();
       }
-      p2d = TheArcTool::Value(recdomain2->Value(), solrst2(1));
+      p2d = TheArcTool::Value(myRecDomain2->Value(), solrst2(1));
       ParSol(1) = solrst2(3);
       ParSol(2) = solrst2(4);
       ParSol(3) = p2d.X();
@@ -352,14 +364,14 @@ Standard_Boolean Blend_Walking::PerformFirstSection (Blend_Function& Func,
     // sol sur 1
     State = Blend_OnRst1;
     param = w1;
-    recdomain1->Init();
+    myRecDomain1->Init();
     nbarc = 1;
     while (nbarc < Index1)
     {
       nbarc++;
-      recdomain1->Next();
+      myRecDomain1->Next();
     }
-    p2d = TheArcTool::Value(recdomain1->Value(), solrst1(1));
+    p2d = TheArcTool::Value(myRecDomain1->Value(), solrst1(1));
     ParSol(1) = p2d.X();
     ParSol(2) = p2d.Y();
     ParSol(3) = solrst1(3);
@@ -375,14 +387,14 @@ Standard_Boolean Blend_Walking::PerformFirstSection (Blend_Function& Func,
     State = Blend_OnRst2;
     param = w2;
     
-    recdomain2->Init();
+    myRecDomain2->Init();
     nbarc = 1;
     while (nbarc < Index2)
     {
       nbarc++;
-      recdomain2->Next();
+      myRecDomain2->Next();
     }
-    p2d = TheArcTool::Value(recdomain2->Value(), solrst2(1));
+    p2d = TheArcTool::Value(myRecDomain2->Value(), solrst2(1));
     ParSol(1) = solrst2(3);
     ParSol(2) = solrst2(4);
     ParSol(3) = p2d.X();
@@ -409,9 +421,9 @@ Standard_Boolean Blend_Walking::PerformFirstSection (Blend_Function& Func,
 #endif
       MakeExtremity(Ext1, Standard_True, Index1, solrst1(1), Isvtx1, Vtx1);
       if (ToCorrectOnRst1)
-        Ext2.SetValue(CorrectedPnt, CorrectedU, CorrectedV, tolesp);
+        Ext2.SetValue(CorrectedPnt, CorrectedU, CorrectedV, my3DTolEsp);
       else
-        Ext2.SetValue(previousP.PointOnS2(), sol(3), sol(4), tolesp);
+        Ext2.SetValue(previousP.PointOnS2(), sol(3), sol(4), my3DTolEsp);
     }
     break;
 
@@ -424,9 +436,9 @@ Standard_Boolean Blend_Walking::PerformFirstSection (Blend_Function& Func,
       }
 #endif
       if (ToCorrectOnRst2)
-        Ext1.SetValue(CorrectedPnt, CorrectedU, CorrectedV, tolesp);
+        Ext1.SetValue(CorrectedPnt, CorrectedU, CorrectedV, my3DTolEsp);
       else
-        Ext1.SetValue(previousP.PointOnS1(), sol(1), sol(2), tolesp);
+        Ext1.SetValue(previousP.PointOnS1(), sol(1), sol(2), my3DTolEsp);
       MakeExtremity(Ext2, Standard_False, Index2, solrst2(1), Isvtx2, Vtx2);
     }
     break;
diff --git a/src/Blend/Blend_Walking_2.gxx b/src/Blend/Blend_Walking_2.gxx
index adb10bd..c5bd68f 100644
--- a/src/Blend/Blend_Walking_2.gxx
+++ b/src/Blend/Blend_Walking_2.gxx
@@ -41,10 +41,9 @@ Blend_Status Blend_Walking::TestArret(Blend_Function& Function,
   IntSurf_TypeTrans tras1,tras2;
   Blend_Point curpoint;
   Standard_Boolean loctwist1 = Standard_False, loctwist2 = Standard_False;
-  Standard_Real tolsolu = tolesp;
+  const Standard_Real aTolSolu = ( !TestSolu)? 1000.0*my3DTolEsp : my3DTolEsp;
 
-  if ( !TestSolu) tolsolu *= 1000; //Ca doit toujours etre bon
-  if (Function.IsSolution(sol,tolsolu)) {
+  if (Function.IsSolution(sol,aTolSolu)) {
 
 #ifdef OCCT_DEBUG
     sectioncalculee = 1;
@@ -211,8 +210,8 @@ Blend_Status Blend_Walking::CheckDeflection
     if(!prevpointistangent){
       prevTg = previousP.TangentOnS1();
     }
-    tolu = TheSurfaceTool::UResolution(surf1,tolesp);
-    tolv = TheSurfaceTool::VResolution(surf1,tolesp);
+    tolu = TheSurfaceTool::UResolution(surf1, my3DTolEsp);
+    tolv = TheSurfaceTool::VResolution(surf1, my3DTolEsp);
   }
   else {
     Psurf = CurPoint.PointOnS2();
@@ -223,8 +222,8 @@ Blend_Status Blend_Walking::CheckDeflection
     if(!prevpointistangent){
       prevTg = previousP.TangentOnS2();
     }
-    tolu = TheSurfaceTool::UResolution(surf2,tolesp);
-    tolv = TheSurfaceTool::VResolution(surf2,tolesp);
+    tolu = TheSurfaceTool::UResolution(surf2, my3DTolEsp);
+    tolv = TheSurfaceTool::VResolution(surf2, my3DTolEsp);
   }
 
   gp_Vec Corde(prevP,Psurf);
@@ -233,12 +232,12 @@ Blend_Status Blend_Walking::CheckDeflection
   if(!prevpointistangent) prevNorme = prevTg.SquareMagnitude();
 
 
-  if (Norme <= tolesp*tolesp){
+  if (Norme <= my3DTolEsp*my3DTolEsp){
     // il faudra peut etre  forcer meme point
     return Blend_SamePoints;
   }
   if(!prevpointistangent){
-    if(prevNorme <= tolesp*tolesp) {
+    if (prevNorme <= my3DTolEsp*my3DTolEsp) {
       return Blend_SamePoints;
     }
     Cosi = sens*Corde*prevTg;
diff --git a/src/Blend/Blend_Walking_3.gxx b/src/Blend/Blend_Walking_3.gxx
index 1a0586c..392cc6e 100644
--- a/src/Blend/Blend_Walking_3.gxx
+++ b/src/Blend/Blend_Walking_3.gxx
@@ -31,12 +31,12 @@ Standard_Integer Blend_Walking::ArcToRecadre(const Standard_Boolean OnFirst,
   if (OnFirst) {
     if(byinter) previousP.ParametersOnS1(uprev,vprev);
     pt2d.SetCoord(theSol(1),theSol(2));
-    Iter = recdomain1;
+    Iter = myRecDomain1;
   }
   else {
     if(byinter) previousP.ParametersOnS2(uprev,vprev);
     pt2d.SetCoord(theSol(3),theSol(4));
-    Iter = recdomain2;
+    Iter = myRecDomain2;
   }
   lastpt2d.SetCoord(uprev,vprev);
   Iter->Init();
@@ -93,8 +93,8 @@ Standard_Boolean Blend_Walking::Recadre(Blend_FuncInv& FuncInv,
   Handle(Adaptor2d_HCurve2d) thecur;
   Handle(TheTopolTool) Iter;
 
-  if (OnFirst) Iter = recdomain1;
-  else         Iter = recdomain2;
+  if (OnFirst) Iter = myRecDomain1;
+  else         Iter = myRecDomain2;
 
   Indexsol = ArcToRecadre(OnFirst, theSol, 0,
 			  lastpt2d, pt2d, pmin);
@@ -125,7 +125,7 @@ Standard_Boolean Blend_Walking::Recadre(Blend_FuncInv& FuncInv,
   infb(2) -= Extrap;
   supb(2) += Extrap;
   
-  FuncInv.GetTolerance(toler,tolesp/10);//Il vaut mieux garder un peu de marge
+  FuncInv.GetTolerance(toler, 0.1*my3DTolEsp);//Il vaut mieux garder un peu de marge
   math_FunctionSetRoot rsnld(FuncInv,toler,35);
   toler *= 10; // Mais on fait les tests correctements
 
@@ -262,7 +262,7 @@ Standard_Boolean Blend_Walking::Recadre(Blend_FuncInv& FuncInv,
       else solrst(1) = pmin;
     }
     // On verifie le jalon
-    jalons_Trouve = (FuncInv.IsSolution(solrst,tolesp));
+    jalons_Trouve = (FuncInv.IsSolution(solrst, my3DTolEsp));
   }
 
   if (!jalons_Trouve) {
@@ -276,7 +276,7 @@ Standard_Boolean Blend_Walking::Recadre(Blend_FuncInv& FuncInv,
     }
     else {
       rsnld.Root(solrst);
-      recadre = FuncInv.IsSolution(solrst,tolesp);
+      recadre = FuncInv.IsSolution(solrst, my3DTolEsp);
     }
   }
 
@@ -310,7 +310,7 @@ Standard_Boolean Blend_Walking::Recadre(Blend_FuncInv& FuncInv,
     // Le probleme a resoudre
     FuncInv.Set(OnFirst,thecur);
     FuncInv.GetBounds(infb,supb);
-    FuncInv.GetTolerance(toler,tolesp/10);//Il vaut mieux garder un peu de marge
+    FuncInv.GetTolerance(toler, 0.1*my3DTolEsp);//Il vaut mieux garder un peu de marge
     math_FunctionSetRoot aRsnld(FuncInv,toler,35);
     toler *= 10; // Mais on fait les tests correctements
     // Resolution...
@@ -324,7 +324,7 @@ Standard_Boolean Blend_Walking::Recadre(Blend_FuncInv& FuncInv,
     }
     else {
       aRsnld.Root(solrst);
-      recadre = FuncInv.IsSolution(solrst,tolesp);
+      recadre = FuncInv.IsSolution(solrst, my3DTolEsp);
     }
   }
 
@@ -451,20 +451,19 @@ void Blend_Walking::MakeExtremity(TheExtremity& Extrem,
   Handle(TheTopolTool) Iter;
 
   if (OnFirst) {
-    Extrem.SetValue(previousP.PointOnS1(),
-		    sol(1),sol(2),
-		    previousP.Parameter(), tolesp);
+    Extrem.SetValue(previousP.PointOnS1(), sol(1),sol(2),
+                    previousP.Parameter(), my3DTolEsp);
     if (!previousP.IsTangencyPoint())  
       Extrem.SetTangent(previousP.TangentOnS1());
-    Iter = recdomain1;
+    Iter = myRecDomain1;
   }
   else {
     Extrem.SetValue(previousP.PointOnS2(),
-		    sol(3),sol(4),
-		    previousP.Parameter(), tolesp);
+                    sol(3),sol(4),
+                    previousP.Parameter(), my3DTolEsp);
     if (!previousP.IsTangencyPoint())  
       Extrem.SetTangent(previousP.TangentOnS2());
-    Iter = recdomain2;
+    Iter = myRecDomain2;
   }
 
   Iter->Init();
@@ -489,14 +488,14 @@ void  Blend_Walking::MakeSingularExtremity( TheExtremity& Extrem,
   Standard_Real prm;
 
   if (OnFirst) {
-    Iter = recdomain1;
+    Iter = myRecDomain1;
     if (!previousP.IsTangencyPoint())
       Extrem.SetTangent(previousP.TangentOnS1());
   }
   else {
     if (!previousP.IsTangencyPoint()) 
       Extrem.SetTangent(previousP.TangentOnS2());
-    Iter = recdomain2;
+    Iter = myRecDomain2;
   }
   
   Iter->Init(); 
diff --git a/src/Blend/Blend_Walking_4.gxx b/src/Blend/Blend_Walking_4.gxx
index 35c38f2..b5eeb0a 100644
--- a/src/Blend/Blend_Walking_4.gxx
+++ b/src/Blend/Blend_Walking_4.gxx
@@ -123,17 +123,17 @@ void Blend_Walking::InternalPerform(Blend_Function& Func,
   Standard_Boolean Arrive,recad1,recad2, control;
   Standard_Boolean Isvtx1 = Standard_False, Isvtx2 = Standard_False, echecrecad;
   gp_Pnt2d p2d;
-  math_Vector tolerance(1,4),infbound(1,4),supbound(1,4),parinit(1,4);
+  math_Vector aVTol2D(1,4),infbound(1,4),supbound(1,4),parinit(1,4);
   math_Vector solrst1(1,4),solrst2(1,4);
   TheVertex Vtx1,Vtx2;
   TheExtremity Ext1,Ext2;
 
   //IntSurf_Transition Tline,Tarc;
 
-  Func.GetTolerance(tolerance,tolesp);
+  Func.GetTolerance(aVTol2D, my3DTolEsp);
   Func.GetBounds(infbound,supbound);
 
-  math_FunctionSetRoot rsnld(Func,tolerance,30);
+  math_FunctionSetRoot rsnld(Func, aVTol2D, 30);
   parinit = sol;
 
   Arrive = Standard_False;
@@ -166,12 +166,10 @@ void Blend_Walking::InternalPerform(Blend_Function& Func,
       stepw = stepw/2.;
       param = parprec + sens*stepw;  // on ne risque pas de depasser Bound.
       if (Abs(stepw) < tolgui) {
-        Ext1.SetValue(previousP.PointOnS1(),
-                      sol(1),sol(2),
-                      previousP.Parameter(),tolesp);
-        Ext2.SetValue(previousP.PointOnS2(),
-                      sol(3),sol(4),
-                      previousP.Parameter(),tolesp);
+        Ext1.SetValue(previousP.PointOnS1(),sol(1),sol(2),
+                      previousP.Parameter(), my3DTolEsp);
+        Ext2.SetValue(previousP.PointOnS2(),sol(3),sol(4),
+                      previousP.Parameter(), my3DTolEsp);
         if (!previousP.IsTangencyPoint()) {
           Ext1.SetTangent(previousP.TangentOnS1());
           Ext2.SetTangent(previousP.TangentOnS2());
@@ -194,12 +192,22 @@ void Blend_Walking::InternalPerform(Blend_Function& Func,
     else {
       rsnld.Root(sol);
 
-      if(clasonS1) situ1 = domain1->Classify(gp_Pnt2d(sol(1),sol(2)),
-					     Min(tolerance(1),tolerance(2)),0);
-      else situ1 = TopAbs_IN;
-      if(clasonS2) situ2 = domain2->Classify(gp_Pnt2d(sol(3),sol(4)),
-					     Min(tolerance(3),tolerance(4)),0);
-      else situ2 = TopAbs_IN;
+      if (clasonS1)
+      {
+        situ1 = myDomain1->Classify(gp_Pnt2d(sol(1), sol(2)), my3DTolEsp, Standard_False);
+      }
+      else
+      {
+        situ1 = TopAbs_IN;
+      }
+      if (clasonS2)
+      {
+        situ2 = myDomain2->Classify(gp_Pnt2d(sol(3), sol(4)), my3DTolEsp, Standard_False);
+      }
+      else
+      {
+        situ2 = TopAbs_IN;
+      }
     }
     if(bonpoint && line->NbPoints() == 1 && (situ1 != TopAbs_IN || situ2 != TopAbs_IN)){
       State = Blend_StepTooLarge;
@@ -222,7 +230,7 @@ void Blend_Walking::InternalPerform(Blend_Function& Func,
 	if (recad1) {
 	  Standard_Real wtemp;
 	  wtemp  = solrst1(2);
-	  if ((param - wtemp)/sens>= -10*tolesp){
+          if ((param - wtemp) / sens >= -10.0 * my3DTolEsp){
 	    w1 = solrst1(2);
 	    control = Standard_True;
 	  }
@@ -248,7 +256,7 @@ void Blend_Walking::InternalPerform(Blend_Function& Func,
 	if (recad2) {
 	  Standard_Real wtemp;
 	  wtemp = solrst2(2);
-	  if ((param - wtemp)/sens>= -10*tolesp){
+          if ((param - wtemp) / sens >= -10.0*my3DTolEsp){
 	    w2 = solrst2(2);
 	    control = Standard_True;
 	  }
@@ -287,17 +295,17 @@ void Blend_Walking::InternalPerform(Blend_Function& Func,
       // Controle effectif des recadrage
       if (control) {
 	TopAbs_State situ;
-	if (recad1 && clasonS2) {
-	  situ = recdomain2->Classify(gp_Pnt2d(solrst1(3),solrst1(4)),
-			              Min(tolerance(3),tolerance(4)));
+	if (recad1 && clasonS2)
+        {
+          situ = myRecDomain2->Classify(gp_Pnt2d(solrst1(3), solrst1(4)), my3DTolEsp, Standard_False);
 	  if (situ == TopAbs_OUT) {
 	    recad1 = Standard_False;
 	    echecrecad = Standard_True;
 	  }
 	}
-	else if (recad2 && clasonS1) {
-	  situ = recdomain1->Classify(gp_Pnt2d(solrst2(3),solrst2(4)),
-			              Min(tolerance(1),tolerance(1)));
+	else if (recad2 && clasonS1)
+        {
+          situ = myRecDomain1->Classify(gp_Pnt2d(solrst2(3), solrst2(4)), my3DTolEsp, Standard_False);
 	  if (situ == TopAbs_OUT) {
 	    recad2 = Standard_False;
 	    echecrecad = Standard_True;
@@ -315,11 +323,11 @@ void Blend_Walking::InternalPerform(Blend_Function& Func,
 	  State = Blend_OnRst12;
 	  param =  (w1+w2)/2;
           gp_Pnt Pnt1, Pnt2;
-	  p2d = TheArcTool::Value(recdomain1->Value(),solrst1(1));
+	  p2d = TheArcTool::Value(myRecDomain1->Value(),solrst1(1));
 	  sol(1) = p2d.X();
 	  sol(2) = p2d.Y();
           Pnt1 = TheSurfaceTool::Value(surf1,sol(1),sol(2));
-	  p2d = TheArcTool::Value(recdomain2->Value(),solrst2(1));
+	  p2d = TheArcTool::Value(myRecDomain2->Value(),solrst2(1));
 	  sol(3) = p2d.X();
 	  sol(4) = p2d.Y();
           Pnt2 = TheSurfaceTool::Value(surf2,sol(3),sol(4));
@@ -384,13 +392,13 @@ void Blend_Walking::InternalPerform(Blend_Function& Func,
 	  // sol sur 1
 	  State = Blend_OnRst1;
 	  param = w1;
-	  recdomain1->Init();
+	  myRecDomain1->Init();
 	  nbarc = 1;
 	  while (nbarc < Index1) {
 	    nbarc++;
-	    recdomain1->Next();
+	    myRecDomain1->Next();
 	  }
-	  p2d = TheArcTool::Value(recdomain1->Value(),solrst1(1));
+	  p2d = TheArcTool::Value(myRecDomain1->Value(),solrst1(1));
 	  sol(1) = p2d.X();
 	  sol(2) = p2d.Y();
 	  sol(3) = solrst1(3);
@@ -412,13 +420,13 @@ void Blend_Walking::InternalPerform(Blend_Function& Func,
 	  State = Blend_OnRst2;
 	  param = w2;
 	  
-	  recdomain2->Init();
+	  myRecDomain2->Init();
 	  nbarc = 1;
 	  while (nbarc < Index2) {
 	    nbarc++;
-	    recdomain2->Next();
+	    myRecDomain2->Next();
 	  }
-	  p2d = TheArcTool::Value(recdomain2->Value(),solrst2(1));
+	  p2d = TheArcTool::Value(myRecDomain2->Value(),solrst2(1));
 	  sol(1) = solrst2(3);
 	  sol(2) = solrst2(4);
 	  sol(3) = p2d.X();
@@ -486,14 +494,12 @@ void Blend_Walking::InternalPerform(Blend_Function& Func,
 
 	parprec = param;
 
-	if (param == Bound) {
-	  Arrive = Standard_True;
-	  Ext1.SetValue(previousP.PointOnS1(),
-			sol(1),sol(2),
-			previousP.Parameter(), tolesp);
-	  Ext2.SetValue(previousP.PointOnS2(),
-			sol(3),sol(4),
-			previousP.Parameter(), tolesp);
+        if (param == Bound) {
+          Arrive = Standard_True;
+          Ext1.SetValue(previousP.PointOnS1(), sol(1),sol(2),
+                        previousP.Parameter(), my3DTolEsp);
+          Ext2.SetValue(previousP.PointOnS2(), sol(3),sol(4),
+                        previousP.Parameter(), my3DTolEsp);
 	  if (!previousP.IsTangencyPoint()) {
 	    Ext1.SetTangent(previousP.TangentOnS1());
 	    Ext2.SetTangent(previousP.TangentOnS2());
@@ -514,14 +520,12 @@ void Blend_Walking::InternalPerform(Blend_Function& Func,
       
     case Blend_StepTooLarge :
       {
-	stepw = stepw/2.;
-	if (Abs(stepw) < tolgui) {
-	  Ext1.SetValue(previousP.PointOnS1(),
-			sol(1),sol(2),
-			previousP.Parameter(),tolesp);
-	  Ext2.SetValue(previousP.PointOnS2(),
-			sol(3),sol(4),
-			previousP.Parameter(),tolesp);
+        stepw = stepw/2.;
+        if (Abs(stepw) < tolgui) {
+          Ext1.SetValue(previousP.PointOnS1(),sol(1),sol(2),
+                        previousP.Parameter(), my3DTolEsp);
+          Ext2.SetValue(previousP.PointOnS2(),sol(3),sol(4),
+                        previousP.Parameter(), my3DTolEsp);
 	  if (!previousP.IsTangencyPoint()) {
 	    Ext1.SetTangent(previousP.TangentOnS1());
 	    Ext2.SetTangent(previousP.TangentOnS2());
@@ -554,15 +558,13 @@ void Blend_Walking::InternalPerform(Blend_Function& Func,
 
 	parprec = param;
 
-	stepw = Min(1.5*stepw,pasmax);
-	if (param == Bound) {
-	  Arrive = Standard_True;
-	  Ext1.SetValue(previousP.PointOnS1(),
-			sol(1),sol(2),
-			previousP.Parameter(),tolesp);
-	  Ext2.SetValue(previousP.PointOnS2(),
-			sol(3),sol(4), 
-			previousP.Parameter(),tolesp);
+        stepw = Min(1.5*stepw,pasmax);
+        if (param == Bound) {
+          Arrive = Standard_True;
+          Ext1.SetValue(previousP.PointOnS1(),sol(1),sol(2),
+                        previousP.Parameter(), my3DTolEsp);
+          Ext2.SetValue(previousP.PointOnS2(),sol(3),sol(4), 
+                        previousP.Parameter(), my3DTolEsp);
 	  if (!previousP.IsTangencyPoint()) {
 	    Ext1.SetTangent(previousP.TangentOnS1());
 	    Ext2.SetTangent(previousP.TangentOnS2());
@@ -591,17 +593,15 @@ void Blend_Walking::InternalPerform(Blend_Function& Func,
 	MakeExtremity(Ext1,Standard_True,Index1,
 		      solrst1(1),Isvtx1,Vtx1);
         // On blinde le cas singulier ou un des recadrage a planter
-        if (previousP.PointOnS1().IsEqual(previousP.PointOnS2(), 2*tolesp)) {
-	  Ext2.SetValue(previousP.PointOnS1(),
-			sol(3),sol(4),tolesp);
-	  if (Isvtx1) MakeSingularExtremity(Ext2, Standard_False, Vtx1);
-	}
-	else {
-	  Ext2.SetValue(previousP.PointOnS2(),
-			sol(3),sol(4),
-			previousP.Parameter(),tolesp);
-	}
-	Arrive = Standard_True;
+        if (previousP.PointOnS1().IsEqual(previousP.PointOnS2(), 2.0 * my3DTolEsp)) {
+          Ext2.SetValue(previousP.PointOnS1(), sol(3), sol(4), my3DTolEsp);
+          if (Isvtx1) MakeSingularExtremity(Ext2, Standard_False, Vtx1);
+        }
+        else {
+          Ext2.SetValue(previousP.PointOnS2(), sol(3),sol(4),
+                        previousP.Parameter(), my3DTolEsp);
+        }
+        Arrive = Standard_True;
       }
       break;
 
@@ -614,15 +614,13 @@ void Blend_Walking::InternalPerform(Blend_Function& Func,
 	  line->Prepend(previousP);
 	}
         // On blinde le cas singulier ou un des recadrage a plante
-        if (previousP.PointOnS1().IsEqual(previousP.PointOnS2(), 2*tolesp)) {
-	  Ext1.SetValue(previousP.PointOnS2(),
-			sol(1),sol(2),tolesp);
-	  if (Isvtx2) MakeSingularExtremity(Ext1, Standard_True, Vtx2);
-	}
-	else {
-	  Ext1.SetValue(previousP.PointOnS1(),
-			sol(1),sol(2),
-			previousP.Parameter(),tolesp);
+        if (previousP.PointOnS1().IsEqual(previousP.PointOnS2(), 2.0*my3DTolEsp)) {
+          Ext1.SetValue(previousP.PointOnS2(), sol(1), sol(2), my3DTolEsp);
+          if (Isvtx2) MakeSingularExtremity(Ext1, Standard_True, Vtx2);
+        }
+        else {
+          Ext1.SetValue(previousP.PointOnS1(),sol(1),sol(2),
+                        previousP.Parameter(), my3DTolEsp);
 	}
 	MakeExtremity(Ext2,Standard_False,Index2,
 		      solrst2(1),Isvtx2,Vtx2);
@@ -641,7 +639,7 @@ void Blend_Walking::InternalPerform(Blend_Function& Func,
 	}
 
 	if ( (Isvtx1 != Isvtx2) &&
-	    (previousP.PointOnS1().IsEqual(previousP.PointOnS2(), 2*tolesp)) ) {
+                (previousP.PointOnS1().IsEqual(previousP.PointOnS2(), 2.0*my3DTolEsp))) {
 	  // On blinde le cas singulier ou un seul recadrage
 	  // est reconnu comme vertex.
 	  if (Isvtx1) {
@@ -664,21 +662,19 @@ void Blend_Walking::InternalPerform(Blend_Function& Func,
 
     case Blend_SamePoints :
       {
-	// On arrete
+        // On arrete
 #ifdef OCCT_DEBUG
-	cout << " Points confondus dans le cheminement" << endl;
+        cout << " Points confondus dans le cheminement" << endl;
 #endif
-	Ext1.SetValue(previousP.PointOnS1(),
-		      sol(1),sol(2),
-		      previousP.Parameter(),tolesp);
-	Ext2.SetValue(previousP.PointOnS2(),
-		      sol(3),sol(4),
-		      previousP.Parameter(),tolesp);;
-	if (!previousP.IsTangencyPoint()) {
-	  Ext1.SetTangent(previousP.TangentOnS1());
-	  Ext2.SetTangent(previousP.TangentOnS2());
-	}
-	Arrive = Standard_True;
+        Ext1.SetValue(previousP.PointOnS1(),sol(1),sol(2),
+                      previousP.Parameter(), my3DTolEsp);
+        Ext2.SetValue(previousP.PointOnS2(),sol(3),sol(4),
+                      previousP.Parameter(), my3DTolEsp);
+        if (!previousP.IsTangencyPoint()) {
+          Ext1.SetTangent(previousP.TangentOnS1());
+          Ext2.SetTangent(previousP.TangentOnS2());
+        }
+        Arrive = Standard_True;
       }
       break;
     default:
@@ -714,7 +710,7 @@ Standard_Boolean Blend_Walking::CorrectExtremityOnOneRst(const Standard_Integer
   if (theElSpine.NbVertices() == 0)
     return Standard_False;
   
-  Handle(TheTopolTool) DomainOfRst = (IndexOfRst == 1)? recdomain1 : recdomain2;
+  Handle(TheTopolTool) DomainOfRst = (IndexOfRst == 1)? myRecDomain1 : myRecDomain2;
   TheSurface SurfOfRst = (IndexOfRst == 1)? surf1 : surf2;
   TheSurface AnotherSurf = (IndexOfRst == 1)? surf2 : surf1;
   
diff --git a/src/CSLib/CSLib_Class2d.cxx b/src/CSLib/CSLib_Class2d.cxx
index 35e84cb..bd78287 100644
--- a/src/CSLib/CSLib_Class2d.cxx
+++ b/src/CSLib/CSLib_Class2d.cxx
@@ -19,306 +19,373 @@
 #include <CSLib_Class2d.hxx>
 #include <gp_Pnt2d.hxx>
 #include <Standard_ConstructionError.hxx>
+#include <Precision.hxx>
+
+static inline Standard_Boolean IsOn(const Standard_Real theTolU,
+                                    const Standard_Real theTolV,
+                                    const Standard_Real thePrevX,
+                                    const Standard_Real thePrevY,
+                                    const Standard_Real theDx,
+                                    const Standard_Real theDy);
 
-static inline 
-  Standard_Real Transform2d(const Standard_Real u,
-			    const Standard_Real umin,
-			    const Standard_Real umaxmumin);
 
 //=======================================================================
-//function : CSLib_Class2d
+//function : Constructor
 //purpose  : 
 //=======================================================================
-CSLib_Class2d::CSLib_Class2d(const TColgp_Array1OfPnt2d& TP2d,
-			     const Standard_Real aTolu,
-			     const Standard_Real aTolv,
-			     const Standard_Real umin,
-			     const Standard_Real vmin,
-			     const Standard_Real umax,
-			     const Standard_Real vmax) 
+CSLib_Class2d::CSLib_Class2d(const TColgp_Array1OfPnt2d& theTP2d,
+                             const Standard_Real theTolu,
+                             const Standard_Real theTolv,
+                             const Standard_Real theUmin,
+                             const Standard_Real theVmin,
+                             const Standard_Real theUmax,
+                             const Standard_Real theVmax) : myPnts2d(0,
+                                                                theTP2d.Length()),
+                                                            myTolU(theTolu),
+                                                            myTolV(theTolv),
+                                                            myUmin(theUmin),
+                                                            myUmax(theUmax),
+                                                            myVmin(theVmin),
+                                                            myVmax(theVmax)
 {
-  Umin=umin;
-  Vmin=vmin;
-  Umax=umax;
-  Vmax=vmax;
-  //
-  if(umax<=umin || vmax<=vmin) { 
-    MyPnts2dX=NULL;
-    MyPnts2dY=NULL;
-    N=0;
+  const size_t aN = theTP2d.Length();
+  if((theUmax <= theUmin) || (theVmax <= theVmin) || (aN == 0))
+  {
+    // Nothing will be created.
+    return;
   }
-  //
-  else {
-    Standard_Integer i, iLower;
-    Standard_Real du,dv,*Pnts2dX,*Pnts2dY, aPrc;   
-    //
-    aPrc=1.e-10;
-    N = TP2d.Length();
-    Tolu = aTolu;
-    Tolv = aTolv;
-    MyPnts2dX = new Standard_Real [N+1];
-    MyPnts2dY = new Standard_Real [N+1];
-    du=umax-umin;
-    dv=vmax-vmin;
-    Pnts2dX = (Standard_Real *)MyPnts2dX;
-    Pnts2dY = (Standard_Real *)MyPnts2dY;
-    //
-    iLower=TP2d.Lower();
-    for(i = 0; i<N; ++i) { 
-      const gp_Pnt2d& aP2D=TP2d(i+iLower);
-      Pnts2dX[i] = Transform2d(aP2D.X(), umin, du);
-      Pnts2dY[i] = Transform2d(aP2D.Y(), vmin, dv);
-    }
-    Pnts2dX[N]=Pnts2dX[0];
-    Pnts2dY[N]=Pnts2dY[0];
-    //
-    if(du>aPrc) {
-      Tolu/=du;
+
+  myTolU = Max(myTolU, Precision::PConfusion());
+  myTolV = Max(myTolV, Precision::PConfusion());
+
+  // The classification algorithm works incorrectly
+  // some segment(s) of the polygon has null length.
+  // The code below forbids creation of such polygons.
+
+  Standard_Integer aCurrIdx = myPnts2d.Lower();
+  gp_Pnt2d aPPrev = theTP2d(theTP2d.Lower());
+  myPnts2d(aCurrIdx).SetCoord(aPPrev.X() - theUmin, aPPrev.Y() - theVmin);
+  for (Standard_Integer i = theTP2d.Lower() + 1; i < theTP2d.Upper(); ++i)
+  {
+    const gp_Pnt2d& aPCur = theTP2d(i);
+
+    if (aPPrev.SquareDistance(aPCur) < gp::Resolution())
+    {
+      continue;
     }
-    if(dv>aPrc) {
-      Tolv/=dv;
+
+    myPnts2d(++aCurrIdx).SetCoord(aPCur.X() - theUmin, aPCur.Y() - theVmin);
+    aPPrev = aPCur;
+  }
+
+  {
+    aPPrev = theTP2d(theTP2d.Lower());
+    const gp_Pnt2d& aPCur = theTP2d(theTP2d.Upper());
+
+    if (aPPrev.SquareDistance(aPCur) > 0.0)
+    {
+      // I.e. SquareDistance(...) != 0
+
+      myPnts2d(++aCurrIdx).SetCoord(aPCur.X() - theUmin, aPCur.Y() - theVmin);
     }
+
+    myPnts2d(++aCurrIdx).SetCoord(aPPrev.X() - theUmin, aPPrev.Y() - theVmin);
+  }
+
+  if (aCurrIdx < myPnts2d.Upper())
+  {
+    myPnts2d.Resize(myPnts2d.Lower(), aCurrIdx, Standard_True);
   }
 }
+
 //=======================================================================
-//function : Destroy
+//function : Classify
 //purpose  : 
 //=======================================================================
-void CSLib_Class2d::Destroy() { 
-  if(MyPnts2dX) { 
-    delete [] (Standard_Real *)MyPnts2dX;
-    MyPnts2dX=NULL;
-  }
-  if(MyPnts2dY) { 
-    delete [] (Standard_Real *)MyPnts2dY;
-    MyPnts2dY=NULL;
-  }
+CSLib_Class2d::PolyState CSLib_Class2d::Classify(const gp_Pnt2d& theP) const
+{
+  return Classify(theP, myTolU, myTolV);
 }
 
-//-- Attention   Table of 0 ------> N + 1 
-//--                      P1 ..... Pn P1
-//--
-//--     1  2  3
-//--     4  0  5
-//--     6  7  8
-//-- 
 //=======================================================================
-//function : SiDans
+//function : Classify
 //purpose  : 
 //=======================================================================
-Standard_Integer CSLib_Class2d::SiDans(const gp_Pnt2d& P) const
+CSLib_Class2d::PolyState CSLib_Class2d::Classify(const gp_Pnt2d& theP,
+                                                 const Standard_Real theTolU,
+                                                 const Standard_Real theTolV) const
 { 
-  if(!N) {
-    return 0;
+  if ((myPnts2d.Size() < 3) || (myUmin > myUmax) || (myVmin > myVmax))
+  {
+    // Return 0 for compatibility with
+    // previous versions of OCCT (it does not
+    // mean that the status is ON).
+
+#ifdef OCCT_DEBUG
+    std::cout << "CSLib_Class2d::Classify(...). No polygon "
+                 "for classification!" << std::endl;
+#endif
+
+    return (PolyState)0;
   }
   //
-  Standard_Real x,y, aTolu, aTolv;
-  //
-  x = P.X(); y = P.Y();
-  aTolu=Tolu*(Umax-Umin);
-  aTolv=Tolv*(Vmax-Vmin);
-  //
-  if(Umin<Umax && Vmin<Vmax)    {
-    if( ( x<(Umin-aTolu) ) || 
-       ( x>(Umax+aTolu) ) || 
-       ( y<(Vmin-aTolv) ) || 
-       ( y>(Vmax+aTolv) ) ) {
-      return -1;
-    }
-    x=Transform2d(x,Umin,Umax-Umin);
-    y=Transform2d(y,Vmin,Vmax-Vmin);
+  Standard_Real aX = theP.X(), aY = theP.Y();
+  if ((theTolU < (myUmin - aX)) ||
+      ((aX - myUmax) > theTolU) ||
+      (theTolV < (myVmin - aY)) ||
+      ((aY - myVmax) > theTolV))
+  {
+    // The point is outside of the UV-bounds
+    return PolyOut;
   }
 
+  aX -= myUmin;
+  aY -= myVmin;
 
-  Standard_Integer res = InternalSiDansOuOn(x,y);
-  if(res==-1) {    
-    return 0;
-  }
-  if(Tolu || Tolv) {
-    if(res != InternalSiDans(x-Tolu,y-Tolv)) return 0;
-    if(res != InternalSiDans(x+Tolu,y-Tolv)) return 0;
-    if(res != InternalSiDans(x-Tolu,y+Tolv)) return 0;
-    if(res != InternalSiDans(x+Tolu,y+Tolv)) return 0; 
-  }
-  //
-  return((res)? 1: -1);
+  return InternalClass(aX, aY, theTolU, theTolV);
 }
+
 //=======================================================================
-//function : SiDans_OnMode
-//purpose  : 
+//function : InternalClass
+//purpose  : Checks if the point P(thePx, thePy) is inside the
+//            given convex polygon.
+//
+// Algorithm description:
+//
+//  1. Catch the moment when some segment of the polygon
+//      intersects the ray from point P in direction {1, 0}.
+//  2. Compute the number of intersections between this ray and
+//      the segments of this polygon.
+//  3. The point P is inside if the number of intersections is even.
+//      The point P is outside if the number of intersections is odd.
+//
+//  This method works wrong in case of tangent the ray with some
+//  segment of polygon. This case must be investigated additionally.
+//  Therefore, the method will return 0 (as ON-status).
+//
+//  ON-status is checked in parallel mode of this algorithm. It is
+//  made by the following steps:
+//
+//  1. A vector V is created joining P with the nearest point of the
+//    considered segment.
+//  2. V is expanded to the two not collinear components: DU and DV.
+//  3. If every coefficient of expanding is less than the corresponding
+//    tolerance (theTolU and theTolV) then the ON-status is returned.
+//
+// ATTENTION!!!
+//  theTolU or/and theTolV can be equal to 0.
 //=======================================================================
-Standard_Integer CSLib_Class2d::SiDans_OnMode(const gp_Pnt2d& P,
-					      const Standard_Real Tol) const
-{ 
-  if(!N){
-    return 0;
-  }
-  //
-  Standard_Real x,y, aTolu, aTolv;
-  //
-  x = P.X(); y = P.Y();
-  aTolu=Tol; 
-  aTolv=Tol; 
-
-  //-- ****** TO DO LATER, ESTIMATE AT EACH POINT Tol2d depending on Tol3d *****
-  if(Umin<Umax && Vmin<Vmax) { 
-    if(x<(Umin-aTolu) || (x>Umax+aTolu) || 
-       (y<Vmin-aTolv) || (y>Vmax+aTolv)) {
-      return -1;
+CSLib_Class2d::PolyState CSLib_Class2d::InternalClass(const Standard_Real thePx,
+                                                      const Standard_Real thePy,
+                                                      const Standard_Real theTolU,
+                                                      const Standard_Real theTolV) const
+{
+#ifdef CSLIB_CLASS2D_DEBUG
+  bool flShow = false;
+
+  if (flShow)
+  {
+    std::cout << "+++ Dump of CSLib_Class2d polygon ++" << std::endl;
+    std::cout << "plane pl 0 0 0 0 0 1" << std::endl;
+    std::cout << "polyclassify -s -c " << thePx+myUmin << " " << thePy + myVmin <<
+                 " -t " << theTolU << " " << theTolV << " ";
+    for (Standard_Integer i = myPnts2d.Lower(); i <= myPnts2d.Upper(); i++)
+    {
+      const gp_Pnt2d &aPCurr = myPnts2d(i);
+      std::cout << "-p " << aPCurr.X() + myUmin << " " << aPCurr.Y() + myVmin << " ";
     }
-    x=Transform2d(x,Umin,Umax-Umin);
-    y=Transform2d(y,Vmin,Vmax-Vmin);
-  }
-  //
-  Standard_Integer res = InternalSiDansOuOn(x,y);
-  if(aTolu || aTolv) {
-    if(res != InternalSiDans(x-aTolu,y-aTolv)) return 0;
-    if(res != InternalSiDans(x+aTolu,y-aTolv)) return 0;
-    if(res != InternalSiDans(x-aTolu,y+aTolv)) return 0;
-    if(res != InternalSiDans(x+aTolu,y+aTolv)) return 0; 
+    std::cout << std::endl << "mkface ff pl wirsrc" << std::endl;
+    std::cout << "v2d; pcurve ff" << std::endl;
+
+    std::cout << "--- Dump of CSLib_Class2d polygon --" << std::endl << std::endl;
   }
-  return((res)? 1: -1);
-}
-//=======================================================================
-//function : InternalSiDans
-//purpose  : 
-//=======================================================================
-Standard_Integer CSLib_Class2d::InternalSiDans(const Standard_Real Px,
-					       const Standard_Real Py) const
-{ 
-  Standard_Integer nbc, i, ip1, SH, NH;
-  Standard_Real *Pnts2dX, *Pnts2dY;
-  Standard_Real  x, y, nx, ny;
-  //
-  nbc = 0;
-  i   = 0;
-  ip1 = 1;
-  Pnts2dX = (Standard_Real *)MyPnts2dX;
-  Pnts2dY = (Standard_Real *)MyPnts2dY;
-  x   = (Pnts2dX[i]-Px);
-  y   = (Pnts2dY[i]-Py);
-  SH  = (y<0.)? -1 : 1;
-  //
-  for(i=0; i<N ; i++,ip1++) { 
-    nx = Pnts2dX[ip1] - Px;
-    ny = Pnts2dY[ip1] - Py;
-    
-    NH = (ny<0.)? -1 : 1;
-    if(NH!=SH) { 
-      if(x>0. && nx>0.) {
-	nbc++;
-      }
-      else { 
-	if(x>0.0 || nx>0.) { 
-	  if((x-y*(nx-x)/(ny-y))>0.) {
-	    nbc++;
-	  }
-	}
-      }
-      SH = NH;
-    }
-    x = nx; y = ny;
+#endif
+
+  // The source polygon is translated.
+  // So, classified point has (0, 0) - coordinates.
+  
+  Standard_Real aPrevX = myPnts2d(0).X() - thePx,
+                aPrevY = myPnts2d(0).Y() - thePy;
+
+  if ((Abs(aPrevX) <= theTolU) && (Abs(aPrevY) <= theTolV))
+  {
+    //If the classified point is in the vertex of
+    //the polygon
+    return PolyOn;
   }
-  return(nbc&1);
-}
-//modified by NIZNHY-PKV Fri Jan 15 09:03:48 2010f
-//=======================================================================
-//function : InternalSiDansOuOn
-//purpose  : same code as above + test on ON (return(-1) in this case
-//=======================================================================
-Standard_Integer CSLib_Class2d::InternalSiDansOuOn(const Standard_Real Px,
-						   const Standard_Real Py) const 
-{ 
-  Standard_Integer nbc, i, ip1, SH, NH, iRet;
-  Standard_Real *Pnts2dX, *Pnts2dY;
-  Standard_Real x, y, nx, ny, aX;
-  Standard_Real aYmin;
-  //
-  nbc = 0;
-  i   = 0;
-  ip1 = 1;
-  Pnts2dX = (Standard_Real *)MyPnts2dX;
-  Pnts2dY = (Standard_Real *)MyPnts2dY;
-  x   = (Pnts2dX[i]-Px);
-  y   = (Pnts2dY[i]-Py);
-  aYmin=y;
-  SH  = (y<0.)? -1 : 1;
-  for(i=0; i<N ; i++, ip1++) { 
-   
-    nx = Pnts2dX[ip1] - Px;
-    ny = Pnts2dY[ip1] - Py;
-    //-- le 14 oct 97 
-    if(nx<Tolu && nx>-Tolu && ny<Tolv && ny>-Tolv) { 
-      iRet=-1;
-      return iRet;
-    }
-    //find Y coordinate of polyline for current X gka
-    //in order to detect possible status ON
-    Standard_Real aDx = (Pnts2dX[ip1] - Pnts2dX[ip1-1]);
-    if( (Pnts2dX[ip1-1] - Px) * nx < 0.)
+
+  const Standard_Real aNullTolV = Epsilon(myVmax - myVmin);
+
+  CSLib_Class2d::PolyState aRetVal = PolyOut;
+
+  const Standard_Integer aN = myPnts2d.Size();
+  for (Standard_Integer i = 1; i < aN; i++)
+  {
+    const Standard_Real aNewX = myPnts2d(i).X() - thePx,
+                        aNewY = myPnts2d(i).Y() - thePy;
+
+    const Standard_Real aDx = aNewX - aPrevX;
+    const Standard_Real aDy = aNewY - aPrevY;
+
+    if ((Abs(aDx) < gp::Resolution()) && (Abs(aDy) < gp::Resolution()))
+      continue;
+
+    if (Abs(aNewY) <= theTolV)
     {
-     
-      Standard_Real aCurPY =  Pnts2dY[ip1] - (Pnts2dY[ip1] - Pnts2dY[ip1-1])/aDx *nx;
-      Standard_Real aDeltaY = aCurPY - Py;
-      if(aDeltaY >= -Tolv && aDeltaY <= Tolv)
+      // The ray goes through some vertex of the polygon
+
+      if (Abs(aPrevY) < theTolV)
       {
-         iRet=-1;
-         return iRet;
+        // Tangential case. Must be investigated by other methods.
+        return (PolyState) 0;
       }
-    }
-    //
-      
-    NH = (ny<0.)? -1 : 1;
-    if(NH!=SH) { 
-      if(x>0. && nx>0.) {
-	nbc++;
+
+      if (Abs(aNewX) <= theTolU)
+      {
+        //If the classified point is in the vertex of
+        //the polygon
+        return PolyOn;
       }
-      else { 
-	if(x>0. || nx>0.) { 
-	  aX=x-y*(nx-x)/(ny-y);
-	  if(aX>0.){
-	    nbc++;
-	  }
-	}
+
+      if ((Abs(aNewY) <= aNullTolV) && (aNewX > 0.0))
+      {
+        // Ray goes exactly through the vertex of the polygon.
+
+        Standard_Real aY1 = aNewY;
+        if (i < aN - 1)
+        {
+          aY1 = myPnts2d(i + 1).Y() - thePy;
+        }
+        else
+        {
+          aY1 = myPnts2d(myPnts2d.Lower() + 1).Y() - thePy;
+        }
+
+        if (aY1*aPrevY < 0.0)
+        {
+          // Case like this
+
+          //        o
+          //      o
+          //x___o_____
+          //    *
+          //    *
+          //    * 
+
+          // x - the classified point;
+          // ___ - ray Y=thePy
+          // *** and ooo - adjacent segments of polygon
+
+          //Change status IN <--> OUT;
+          aRetVal = (PolyState) -aRetVal;
+        }
+
+        // Case like this
+
+        //x________ 
+        //     *o
+        //    *  o
+        //   *    o
+
+        // must be ignored.
+
+        if (IsOn(theTolU, theTolV, aPrevX, aPrevY, aDx, aDy))
+        {
+          return PolyOn;
+        }
+
+        aPrevX = aNewX;
+        aPrevY = aNewY;
+        continue;
       }
-      SH = NH;
     }
-    else {// y has same sign as ny  
-      if (ny<aYmin) {
-	aYmin=ny;
+
+    if (IsOn(theTolU, theTolV, aPrevX, aPrevY, aDx, aDy))
+    {
+      return PolyOn;
+    }
+
+    if (Abs(aPrevY) <= aNullTolV)
+    {
+      // Ray goes exactly through the vertex of the polygon.
+      // This case was processed earlier.
+
+      aPrevX = aNewX;
+      aPrevY = aNewY;
+      continue;
+    }
+
+    if (aNewY*aPrevY <= 0.0)
+    {
+      // The current segment intersects the line Y=thePy.
+      // X-coord. of the intersection point is
+      const Standard_Real aXi = aPrevX - aPrevY*aDx / aDy;
+
+      //Note.
+      // (aDy==0.0) if and only if (aNewY==aPrevY).
+      // At that, (aNewY*aPrevY <= 0.0) <==> (aNewY==aPrevY==0.0).
+      // Therefore, the condition above must be satisfied and
+      // the method will return 0.
+      // Consequently, here (aDy != 0.0) and aXi is found unambiguously.
+
+      if (aXi > 0.0)
+      {
+        // The current segment intersects the ray Y=thePy
+
+        //Change status IN <--> OUT;
+        aRetVal = (PolyState) -aRetVal;
       }
     }
-    x = nx; y = ny; 
-  }// for(i=0; i<N ; i++,ip1++) { 
- 
-  iRet=nbc&1;
-  return iRet;
-}
-//modified by NIZNHY-PKV Fri Jan 15 09:03:55 2010t
-//=======================================================================
-//function : Copy
-//purpose  : 
-//=======================================================================
-const CSLib_Class2d& CSLib_Class2d::Copy(const CSLib_Class2d& ) const 
-{ 
-#ifdef OCCT_DEBUG
-  cerr<<"Copy not allowed in CSLib_Class2d"<<endl;
-#endif
-  throw Standard_ConstructionError();
+
+    aPrevX = aNewX;
+    aPrevY = aNewY;
+  }
+
+  return aRetVal;
 }
+
 //=======================================================================
-//function : Transform2d
-//purpose  : 
+//function : IsOn
+//purpose  : If the line (which the current segment lies in) has
+//            the location L(thePrevX, thePrevY) and the direction
+//            d{theDx, theDy} then the parameter of the classified
+//            point (0, 0) on the line (i.e. the projection point) is
+//              t = (d*V)/|| d || = -(aPrevX*aDx+aPrevY*aDy)/|| d ||,
+//            where V{-thePrevX, -thePrevY} is the vector joining L with
+//            the classified point (0, 0).
+//            If the projection point is IN the current segment then
+//            the inequation
+//              0 <= t <= || d ||
+//            must be satisfied.
+//            Or
+//              0 <= -(thePrevX*theDx+thePrevY*theDy) <= || d ||^2.
 //=======================================================================
-Standard_Real Transform2d(const Standard_Real u,
-			  const Standard_Real umin,
-			  const Standard_Real umaxmumin) 
-{ 
-  if(umaxmumin>1e-10) { 
-    Standard_Real U = (u-umin)/umaxmumin;
-    return U;
-  }
-  else { 
-    return u;
+static inline Standard_Boolean IsOn(const Standard_Real theTolU,
+                                    const Standard_Real theTolV,
+                                    const Standard_Real thePrevX,
+                                    const Standard_Real thePrevY,
+                                    const Standard_Real theDx,
+                                    const Standard_Real theDy)
+{
+  //Square length of the considered segment
+  //aSqL != 0 (see algorithm of polygon building in constructor).
+  const Standard_Real aSqL = theDx*theDx + theDy*theDy;
+  const Standard_Real aDP = theDx*thePrevX + theDy*thePrevY;
+  if ((-aSqL <= aDP) && (aDP <= 0.0))
+  {
+    // The projection point has coordinates
+    //    L + t*d/|| d || = L - d*(aPrevX*aDx+aPrevY*aDy)/aSqL
+
+    const Standard_Real aXNear = thePrevX - aDP*theDx / aSqL;
+    const Standard_Real aYNear = thePrevY - aDP*theDy / aSqL;
+
+    if ((Abs(aXNear) <= theTolU) && (Abs(aYNear) <= theTolV))
+    {
+      // The distance between the projection point and 
+      // the classified point (0, 0) is in the given tolerances
+      return Standard_True;
+    }
   }
+
+  return Standard_False;
 }
diff --git a/src/CSLib/CSLib_Class2d.hxx b/src/CSLib/CSLib_Class2d.hxx
index 96478dd..9495c5a 100644
--- a/src/CSLib/CSLib_Class2d.hxx
+++ b/src/CSLib/CSLib_Class2d.hxx
@@ -21,75 +21,78 @@
 #include <Standard_DefineAlloc.hxx>
 #include <Standard_Handle.hxx>
 
-#include <Standard_Address.hxx>
-#include <Standard_Real.hxx>
-#include <Standard_Integer.hxx>
+#include <NCollection_Array1.hxx>
 #include <TColgp_Array1OfPnt2d.hxx>
 class gp_Pnt2d;
 
 
-
-//! *** Class2d    : Low level algorithm for 2d classification
-//! this class was moved from package BRepTopAdaptor
+//! Performs the classification of the given 2D-point
+//! relatively to the closed 2D-polygon.
+//! The orientation of the polygon is NOT taken into account.
+//! Returns ON-status if computation is impossible.
 class CSLib_Class2d 
 {
 public:
 
   DEFINE_STANDARD_ALLOC
 
+  enum PolyState
+  {
+    PolyOut = -1,
+    PolyOn = 0,
+    PolyIn = 1
+  };
+
+  //! Constructs the 2D-polygon.
+  //! theTP2d is the set of the vertices (closed polygon
+  //! will always be created inside of this constructor;
+  //! consequently, there is no point in repeating first and
+  //! last point in theTP2d).
+  //! theTolu and theTolv are tolerances.
+  //! theUmin, theVmin, theUmax, theVmax are
+  //! UV-bounds of the polygon.
+  Standard_EXPORT CSLib_Class2d(const TColgp_Array1OfPnt2d& theTP2d,
+                                const Standard_Real theTolu,
+                                const Standard_Real theTolv,
+                                const Standard_Real theUmin,
+                                const Standard_Real theVmin,
+                                const Standard_Real theUmax,
+                                const Standard_Real theVmax);
   
-  Standard_EXPORT CSLib_Class2d(const TColgp_Array1OfPnt2d& TP, const Standard_Real aTolu, const Standard_Real aTolv, const Standard_Real umin, const Standard_Real vmin, const Standard_Real umax, const Standard_Real vmax);
-  
-  Standard_EXPORT Standard_Integer SiDans (const gp_Pnt2d& P) const;
-  
-  Standard_EXPORT Standard_Integer SiDans_OnMode (const gp_Pnt2d& P, const Standard_Real Tol) const;
+  //! Classifies theP relatively to the polygon.
+  //! Uses internal tolerances (myTolU, myTolV).
+  Standard_EXPORT PolyState Classify(const gp_Pnt2d& theP) const;
   
-  Standard_EXPORT Standard_Integer InternalSiDans (const Standard_Real X, const Standard_Real Y) const;
-  
-  Standard_EXPORT Standard_Integer InternalSiDansOuOn (const Standard_Real X, const Standard_Real Y) const;
-  
-  Standard_EXPORT const CSLib_Class2d& Copy (const CSLib_Class2d& Other) const;
-const CSLib_Class2d& operator= (const CSLib_Class2d& Other) const
-{
-  return Copy(Other);
-}
+  //! Classifies theP relatively to the polygon.
+  //! Uses given tolerances (theTolU, theTolV).
+  Standard_EXPORT PolyState Classify(const gp_Pnt2d& theP,
+                                     const Standard_Real theTolU,
+                                     const Standard_Real theTolV) const;
   
-  Standard_EXPORT void Destroy();
-~CSLib_Class2d()
-{
-  Destroy();
-}
-
-
-
-
 protected:
 
+  //! Classifies theP relatively to the polygon.
+  //! Uses internal tolerances (myTolU, myTolV).
+  //! Realizes the algorithm itself.
+  Standard_EXPORT PolyState InternalClass(const Standard_Real thePx,
+                                          const Standard_Real thePy,
+                                          const Standard_Real theTolU,
+                                          const Standard_Real theTolV) const;
 
-
-
+  //! Assignment operator is disabled for this class.
+  const CSLib_Class2d& operator= (const CSLib_Class2d& Other) const;
 
 private:
+  
+  //! Stores set of vertices of the given 2D-polygons
+  TColgp_Array1OfPnt2d myPnts2d;
 
+  //! Tolerances
+  Standard_Real myTolU, myTolV;
 
-
-  Standard_Address MyPnts2dX;
-  Standard_Address MyPnts2dY;
-  Standard_Real Tolu;
-  Standard_Real Tolv;
-  Standard_Integer N;
-  Standard_Real Umin;
-  Standard_Real Vmin;
-  Standard_Real Umax;
-  Standard_Real Vmax;
-
+  //! UV-bounds of the polygon
+  Standard_Real myUmin, myUmax, myVmin, myVmax;
 
 };
 
-
-
-
-
-
-
 #endif // _CSLib_Class2d_HeaderFile
diff --git a/src/ChFi3d/ChFi3d_Builder.hxx b/src/ChFi3d/ChFi3d_Builder.hxx
index 238c0b8..a7b380a 100644
--- a/src/ChFi3d/ChFi3d_Builder.hxx
+++ b/src/ChFi3d/ChFi3d_Builder.hxx
@@ -233,22 +233,22 @@ protected:
   
   Standard_EXPORT void CallPerformSurf (Handle(ChFiDS_Stripe)& Stripe, const Standard_Boolean Simul, ChFiDS_SequenceOfSurfData& SeqSD, Handle(ChFiDS_SurfData)& SD, const Handle(ChFiDS_HElSpine)& Guide, const Handle(ChFiDS_Spine)& Spine, const Handle(BRepAdaptor_HSurface)& HS1, const Handle(BRepAdaptor_HSurface)& HS3, const gp_Pnt2d& P1, const gp_Pnt2d& P3, const Handle(Adaptor3d_TopolTool)& I1, const Handle(BRepAdaptor_HSurface)& HS2, const Handle(BRepAdaptor_HSurface)& HS4, const gp_Pnt2d& P2, const gp_Pnt2d& P4, const Handle(Adaptor3d_TopolTool)& I2, const Standard_Real MaxStep, const Standard_Real Fleche, const Standard_Real TolGuide, Standard_Real& First, Standard_Real& Last, const Standard_Boolean Inside, const Standard_Boolean Appro, const Standard_Boolean Forward, const Standard_Boolean RecOnS1, const Standard_Boolean RecOnS2, math_Vector& Soldep, Standard_Integer& Intf, Standard_Integer& Intl, Handle(BRepAdaptor_HSurface)& Surf1, Handle(BRepAdaptor_HSurface)& Surf2);
   
-  //! Method, implemented in the inheritants, calculating
+  //! Method, implemented in the inheritance, calculating
   //! elements of construction of the surface (fillet or
   //! chamfer).
   Standard_EXPORT virtual Standard_Boolean PerformSurf (ChFiDS_SequenceOfSurfData& Data, const Handle(ChFiDS_HElSpine)& Guide, const Handle(ChFiDS_Spine)& Spine, const Standard_Integer Choix, const Handle(BRepAdaptor_HSurface)& S1, const Handle(Adaptor3d_TopolTool)& I1, const Handle(BRepAdaptor_HSurface)& S2, const Handle(Adaptor3d_TopolTool)& I2, const Standard_Real MaxStep, const Standard_Real Fleche, const Standard_Real TolGuide, Standard_Real& First, Standard_Real& Last, const Standard_Boolean Inside, const Standard_Boolean Appro, const Standard_Boolean Forward, const Standard_Boolean RecOnS1, const Standard_Boolean RecOnS2, const math_Vector& Soldep, Standard_Integer& Intf, Standard_Integer& Intl) = 0;
   
-  //! Method, implemented  in inheritants, calculates
+  //! Method, implemented  in inheritance, calculates
   //! the elements of construction of  the surface (fillet
   //! or chamfer) contact edge/face.
   Standard_EXPORT virtual void PerformSurf (ChFiDS_SequenceOfSurfData& Data, const Handle(ChFiDS_HElSpine)& Guide, const Handle(ChFiDS_Spine)& Spine, const Standard_Integer Choix, const Handle(BRepAdaptor_HSurface)& S1, const Handle(Adaptor3d_TopolTool)& I1, const Handle(BRepAdaptor_HCurve2d)& PC1, const Handle(BRepAdaptor_HSurface)& Sref1, const Handle(BRepAdaptor_HCurve2d)& PCref1, Standard_Boolean& Decroch1, const Handle(BRepAdaptor_HSurface)& S2, const Handle(Adaptor3d_TopolTool)& I2, const TopAbs_Orientation Or2, const Standard_Real MaxStep, const Standard_Real Fleche, const Standard_Real TolGuide, Standard_Real& First, Standard_Real& Last, const Standard_Boolean Inside, const Standard_Boolean Appro, const Standard_Boolean Forward, const Standard_Boolean RecP, const Standard_Boolean RecS, const Standard_Boolean RecRst, const math_Vector& Soldep);
   
-  //! Method, implemented in  inheritants, calculates
+  //! Method, implemented in  inheritance, calculates
   //! the elements of construction of  the surface (fillet
   //! or chamfer) contact edge/face.
   Standard_EXPORT virtual void PerformSurf (ChFiDS_SequenceOfSurfData& Data, const Handle(ChFiDS_HElSpine)& Guide, const Handle(ChFiDS_Spine)& Spine, const Standard_Integer Choix, const Handle(BRepAdaptor_HSurface)& S1, const Handle(Adaptor3d_TopolTool)& I1, const TopAbs_Orientation Or1, const Handle(BRepAdaptor_HSurface)& S2, const Handle(Adaptor3d_TopolTool)& I2, const Handle(BRepAdaptor_HCurve2d)& PC2, const Handle(BRepAdaptor_HSurface)& Sref2, const Handle(BRepAdaptor_HCurve2d)& PCref2, Standard_Boolean& Decroch2, const Standard_Real MaxStep, const Standard_Real Fleche, const Standard_Real TolGuide, Standard_Real& First, Standard_Real& Last, const Standard_Boolean Inside, const Standard_Boolean Appro, const Standard_Boolean Forward, const Standard_Boolean RecP, const Standard_Boolean RecS, const Standard_Boolean RecRst, const math_Vector& Soldep);
   
-  //! Method, implemented in inheritants, calculates
+  //! Method, implemented in inheritance, calculates
   //! the elements of construction of  the surface (fillet
   //! or chamfer) contact edge/edge.
   Standard_EXPORT virtual void PerformSurf (ChFiDS_SequenceOfSurfData& Data, const Handle(ChFiDS_HElSpine)& Guide, const Handle(ChFiDS_Spine)& Spine, const Standard_Integer Choix, const Handle(BRepAdaptor_HSurface)& S1, const Handle(Adaptor3d_TopolTool)& I1, const Handle(BRepAdaptor_HCurve2d)& PC1, const Handle(BRepAdaptor_HSurface)& Sref1, const Handle(BRepAdaptor_HCurve2d)& PCref1, Standard_Boolean& Decroch1, const TopAbs_Orientation Or1, const Handle(BRepAdaptor_HSurface)& S2, const Handle(Adaptor3d_TopolTool)& I2, const Handle(BRepAdaptor_HCurve2d)& PC2, const Handle(BRepAdaptor_HSurface)& Sref2, const Handle(BRepAdaptor_HCurve2d)& PCref2, Standard_Boolean& Decroch2, const TopAbs_Orientation Or2, const Standard_Real MaxStep, const Standard_Real Fleche, const Standard_Real TolGuide, Standard_Real& First, Standard_Real& Last, const Standard_Boolean Inside, const Standard_Boolean Appro, const Standard_Boolean Forward, const Standard_Boolean RecP1, const Standard_Boolean RecRst1, const Standard_Boolean RecP2, const Standard_Boolean RecRst2, const math_Vector& Soldep);
@@ -290,34 +290,6 @@ protected:
   
   Standard_EXPORT Standard_Boolean CompleteData (Handle(ChFiDS_SurfData)& Data, const Handle(Geom_Surface)& Surfcoin, const Handle(Adaptor3d_HSurface)& S1, const Handle(Geom2d_Curve)& PC1, const Handle(Adaptor3d_HSurface)& S2, const Handle(Geom2d_Curve)& PC2, const TopAbs_Orientation Or, const Standard_Boolean On1, const Standard_Boolean Gd1, const Standard_Boolean Gd2, const Standard_Boolean Gf1, const Standard_Boolean Gf2);
 
-
-  Standard_Real tolappangle;
-  Standard_Real tolesp;
-  Standard_Real tol2d;
-  Standard_Real tolapp3d;
-  Standard_Real tolapp2d;
-  Standard_Real fleche;
-  GeomAbs_Shape myConti;
-  ChFiDS_Map myEFMap;
-  ChFiDS_Map myESoMap;
-  ChFiDS_Map myEShMap;
-  ChFiDS_Map myVFMap;
-  ChFiDS_Map myVEMap;
-  Handle(TopOpeBRepDS_HDataStructure) myDS;
-  Handle(TopOpeBRepBuild_HBuilder) myCoup;
-  ChFiDS_ListOfStripe myListStripe;
-  ChFiDS_StripeMap myVDataMap;
-  ChFiDS_Regularities myRegul;
-  ChFiDS_ListOfStripe badstripes;
-  TopTools_ListOfShape badvertices;
-  TopTools_DataMapOfShapeListOfInteger myEVIMap;
-  Standard_Boolean done;
-  Standard_Boolean hasresult;
-
-
-private:
-
-  
   Standard_EXPORT Standard_Boolean FaceTangency (const TopoDS_Edge& E0, const TopoDS_Edge& E1, const TopoDS_Vertex& V) const;
   
   Standard_EXPORT void PerformSetOfSurfOnElSpine (const Handle(ChFiDS_HElSpine)& ES, Handle(ChFiDS_Stripe)& St, Handle(BRepTopAdaptor_TopolTool)& It1, Handle(BRepTopAdaptor_TopolTool)& It2, const Standard_Boolean Simul = Standard_False);
@@ -348,6 +320,31 @@ private:
   
   Standard_EXPORT void ConexFaces (const Handle(ChFiDS_Spine)& Sp, const Standard_Integer IEdge, const Standard_Integer RefChoix, Handle(BRepAdaptor_HSurface)& HS1, Handle(BRepAdaptor_HSurface)& HS2) const;
 
+  Standard_Real tolappangle;
+  Standard_Real tolesp;
+  Standard_Real tol2d;
+  Standard_Real tolapp3d;
+  Standard_Real tolapp2d;
+  Standard_Real fleche;
+  GeomAbs_Shape myConti;
+  ChFiDS_Map myEFMap;
+  ChFiDS_Map myESoMap;
+  ChFiDS_Map myEShMap;
+  ChFiDS_Map myVFMap;
+  ChFiDS_Map myVEMap;
+  Handle(TopOpeBRepDS_HDataStructure) myDS;
+  Handle(TopOpeBRepBuild_HBuilder) myCoup;
+  ChFiDS_ListOfStripe myListStripe;
+  ChFiDS_StripeMap myVDataMap;
+  ChFiDS_Regularities myRegul;
+  ChFiDS_ListOfStripe badstripes;
+  TopTools_ListOfShape badvertices;
+  TopTools_DataMapOfShapeListOfInteger myEVIMap;
+  Standard_Boolean done;
+  Standard_Boolean hasresult;
+
+
+private:
 
   TopoDS_Shape myShape;
   Standard_Real angular;
diff --git a/src/ChFi3d/ChFi3d_Builder_0.cxx b/src/ChFi3d/ChFi3d_Builder_0.cxx
index fd166d3..19c8526 100644
--- a/src/ChFi3d/ChFi3d_Builder_0.cxx
+++ b/src/ChFi3d/ChFi3d_Builder_0.cxx
@@ -2951,8 +2951,7 @@ Standard_Real ChFi3d_EvalTolReached(const Handle(Adaptor3d_HSurface)& S1,
 //function : trsfsurf
 //purpose  : 
 //=======================================================================
-Handle(Geom_Surface) trsfsurf(const Handle(Adaptor3d_HSurface)& HS,
-  Handle(Adaptor3d_TopolTool)&      /*dom*/)
+Handle(Geom_Surface) trsfsurf(const Handle(Adaptor3d_HSurface)& HS)
 {
   //Pour l utilisation des domaines voir avec BUBUCH!!
   Handle(Geom_Surface) res;
@@ -3184,9 +3183,8 @@ Standard_Boolean ChFi3d_ComputeCurves(const Handle(Adaptor3d_HSurface)&   S1,
   }
   else {
     // here GeomInt is approached.
-    Handle(Adaptor3d_TopolTool) dom1,dom2;
-    Handle(Geom_Surface) gs1 = trsfsurf(S1,dom1);
-    Handle(Geom_Surface) gs2 = trsfsurf(S2,dom2);
+    Handle(Geom_Surface) gs1 = trsfsurf(S1);
+    Handle(Geom_Surface) gs2 = trsfsurf(S2);
     Standard_Integer nbl ;
     if(!gs1.IsNull() && !gs2.IsNull()) {
       GeomInt_IntSS inter;
diff --git a/src/ChFi3d/ChFi3d_Builder_2.cxx b/src/ChFi3d/ChFi3d_Builder_2.cxx
index c7d003f..da94ada 100644
--- a/src/ChFi3d/ChFi3d_Builder_2.cxx
+++ b/src/ChFi3d/ChFi3d_Builder_2.cxx
@@ -858,14 +858,14 @@ void ChFi3d_Builder::StartSol(const Handle(ChFiDS_Stripe)&      Stripe,
       ResV = AS.VResolution(TolE);
       derive *= 2*(Abs(derive.X())*ResU + Abs(derive.Y())*ResV);
       P2d = P1.Translated(derive);
-      if (I1->Classify(P2d, Min(ResU, ResV), 0)== TopAbs_IN) {
-	P1 = P2d;
+      if (I1->Classify(P2d, TolE, Standard_False) == TopAbs_IN) {
+        P1 = P2d;
       }
       else {
-	 P2d = P1.Translated(-derive);
-	 if (I1->Classify(P2d, Min(ResU, ResV), 0)== TopAbs_IN) {
-	   P1 = P2d;
-	 }
+         P2d = P1.Translated(-derive);
+         if (I1->Classify(P2d, TolE, Standard_False) == TopAbs_IN) {
+           P1 = P2d;
+         }
       }
     }
     if(f1.IsSame(f2)) cured.Orientation(TopAbs_REVERSED);
diff --git a/src/ChFi3d/ChFi3d_Builder_SpKP.cxx b/src/ChFi3d/ChFi3d_Builder_SpKP.cxx
index a4b2cd2..2d79670 100644
--- a/src/ChFi3d/ChFi3d_Builder_SpKP.cxx
+++ b/src/ChFi3d/ChFi3d_Builder_SpKP.cxx
@@ -780,7 +780,7 @@ Standard_Boolean ChFi3d_Builder::SplitKPart
     // It is checked if the point 2d of the degenerated edge is in the face.
     if (C1.IsNull()) {
       gp_Pnt2d p2d1 = CD->Get2dPoints(0,1);
-      TopAbs_State situ = I1->Classify(p2d1,1.e-8,0);
+      TopAbs_State situ = I1->Classify(p2d1,Precision::Confusion(),Standard_False);
       if(situ == TopAbs_OUT) return Standard_False;
     }
 
@@ -815,7 +815,7 @@ Standard_Boolean ChFi3d_Builder::SplitKPart
     // It is checked if the point 2d of the degenerated is in the face.
     if (C2.IsNull()) {
       gp_Pnt2d p2d2 = CD->Get2dPoints(0,2);
-      TopAbs_State situ = I2->Classify(p2d2,1.e-8,0);
+      TopAbs_State situ = I2->Classify(p2d2,Precision::Confusion(),Standard_False);
       if(situ == TopAbs_OUT) return Standard_False;
     }
 
diff --git a/src/ChFi3d/ChFi3d_ChBuilder.hxx b/src/ChFi3d/ChFi3d_ChBuilder.hxx
index c9662ac..ecd4474 100644
--- a/src/ChFi3d/ChFi3d_ChBuilder.hxx
+++ b/src/ChFi3d/ChFi3d_ChBuilder.hxx
@@ -189,13 +189,13 @@ protected:
   //! set the regularities
   Standard_EXPORT void SetRegul() Standard_OVERRIDE;
 
+  Standard_EXPORT void ConexFaces (const Handle(ChFiDS_Spine)& Sp, const Standard_Integer IEdge, TopoDS_Face& F1, TopoDS_Face& F2) const;
 
 
 
 private:
 
   
-  Standard_EXPORT void ConexFaces (const Handle(ChFiDS_Spine)& Sp, const Standard_Integer IEdge, TopoDS_Face& F1, TopoDS_Face& F2) const;
 
 
 
diff --git a/src/ChFi3d/ChFi3d_ChBuilder_C3.cxx b/src/ChFi3d/ChFi3d_ChBuilder_C3.cxx
index 7dca1c2..b5df8a0 100644
--- a/src/ChFi3d/ChFi3d_ChBuilder_C3.cxx
+++ b/src/ChFi3d/ChFi3d_ChBuilder_C3.cxx
@@ -354,10 +354,8 @@ void ChFi3d_ChBuilder::PerformThreeCorner(const Standard_Integer Jndex)
   Handle(BRepAdaptor_HSurface) Fac = new BRepAdaptor_HSurface(face[pivot]);
   Handle(GeomAdaptor_HSurface) 
     bidsurf = new GeomAdaptor_HSurface(Fac->ChangeSurface().Surface());
-  Handle(Adaptor3d_TopolTool)  IFac = new Adaptor3d_TopolTool(bidsurf);
 
   Handle(GeomAdaptor_HSurface) Surf = ChFi3d_BoundSurf (DStr,fdpiv,jf[pivot][deb],jf[pivot][fin]);
-  Handle(Adaptor3d_TopolTool) ISurf = new Adaptor3d_TopolTool(Surf);
  
   // Creation of a new Stripe for the corner
   Handle(ChFiDS_Stripe) corner = new ChFiDS_Stripe();
diff --git a/src/ChFi3d/ChFi3d_FilBuilder_C3.cxx b/src/ChFi3d/ChFi3d_FilBuilder_C3.cxx
index 732c6cf..cd86e3a 100644
--- a/src/ChFi3d/ChFi3d_FilBuilder_C3.cxx
+++ b/src/ChFi3d/ChFi3d_FilBuilder_C3.cxx
@@ -438,8 +438,7 @@ void ChFi3d_FilBuilder::PerformThreeCorner(const Standard_Integer Jndex)
   // the border.  
   Handle(GeomAdaptor_HSurface) 
     bidsurf = new GeomAdaptor_HSurface(Fac->ChangeSurface().Surface());
-  Handle(Adaptor3d_TopolTool) 
-    IFac = new Adaptor3d_TopolTool(bidsurf);
+  Handle(Adaptor3d_TopolTool) IFac = new Adaptor3d_TopolTool(bidsurf);
   // end of the attempt.
   Handle(Adaptor3d_TopolTool) ISurf = new Adaptor3d_TopolTool(Surf);
   Handle(ChFiDS_Stripe) corner = new ChFiDS_Stripe();
diff --git a/src/Contap/Contap_Contour.cxx b/src/Contap/Contap_Contour.cxx
index d23c73f..89a181d 100644
--- a/src/Contap/Contap_Contour.cxx
+++ b/src/Contap/Contap_Contour.cxx
@@ -280,13 +280,12 @@ static void Recadre(const Handle(Adaptor3d_HSurface)& myHS1,
 
 
 static void LineConstructor(Contap_TheSequenceOfLine& slin,
-                            const Handle(Adaptor3d_TopolTool)& Domain,
+                            const Handle(Adaptor3d_TopolTool)& theDomain,
                             Contap_Line& L,
                             const Handle(Adaptor3d_HSurface)& Surf) { 
 
                               //-- ------------------------------------------------------------
                               //-- on decoupe la ligne en portions  entre 2 vertex 
-                              Standard_Real Tol = Precision::PConfusion();
                               Contap_IType typl = L.TypeContour();
                               //-- cout<<"\n ----------- Ligne Constructor "<<endl;
                               if(typl == Contap_Walking) { 
@@ -301,7 +300,8 @@ static void LineConstructor(Contap_TheSequenceOfLine& slin,
                                     const IntSurf_PntOn2S& Pmid = L.Point(pmid);
                                     Pmid.Parameters(u1,v1,u2,v2);
                                     Recadre(Surf,u2,v2);
-                                    TopAbs_State in2 = Domain->Classify(gp_Pnt2d(u2,v2),Tol);
+                                    TopAbs_State in2 = theDomain->Classify(gp_Pnt2d(u2, v2),
+                                                                           Precision::Confusion());
                                     if(in2 == TopAbs_OUT) { 
                                     }
                                     else { 
@@ -352,7 +352,8 @@ static void LineConstructor(Contap_TheSequenceOfLine& slin,
                                     }
 
                                     Recadre(Surf,u2,v2);
-                                    TopAbs_State in2 = Domain->Classify(gp_Pnt2d(u2,v2),Tol);
+                                    TopAbs_State in2 = theDomain->Classify(gp_Pnt2d(u2, v2),
+                                                                           Precision::Confusion());
                                     if(in2 == TopAbs_OUT) { 
                                     }
                                     else { 
@@ -399,7 +400,8 @@ static void LineConstructor(Contap_TheSequenceOfLine& slin,
                                     }
 
                                     Recadre(Surf,u2,v2);
-                                    TopAbs_State in2 = Domain->Classify(gp_Pnt2d(u2,v2),Tol);
+                                    TopAbs_State in2 = theDomain->Classify(gp_Pnt2d(u2, v2),
+                                                                           Precision::Confusion());
                                     if(in2 == TopAbs_OUT) { 
                                     }
                                     else { 
@@ -438,7 +440,8 @@ static void LineConstructor(Contap_TheSequenceOfLine& slin,
                                     }
 
                                     Recadre(Surf,u2,v2);
-                                    TopAbs_State in2 = Domain->Classify(gp_Pnt2d(u2,v2),Tol);
+                                    TopAbs_State in2 = theDomain->Classify(gp_Pnt2d(u2, v2),
+                                                                           Precision::Confusion());
                                     if(in2 == TopAbs_OUT) { 
                                     }
                                     else { 
@@ -505,7 +508,7 @@ static void KeepInsidePoints(const Contap_TheSearchInside& solins,
 
 
 static void ComputeTangency (const Contap_TheSearch& solrst,
-                             const Handle(Adaptor3d_TopolTool)& Domain,
+                             const Handle(Adaptor3d_TopolTool)& theDomain,
                              Contap_SurfFunction& Func,
                              IntSurf_SequenceOfPathPoint& seqpdep,
                              TColStd_Array1OfInteger& Destination)
@@ -561,7 +564,7 @@ static void ComputeTangency (const Contap_TheSearch& solrst,
           }
       }
       if(SurUneRestrictionSolution == Standard_False) { 
-        arcorien = Domain->Orientation(thearc);
+        arcorien = theDomain->Orientation(thearc);
         ispassing = (arcorien == TopAbs_INTERNAL ||
           arcorien == TopAbs_EXTERNAL);
 
@@ -581,10 +584,10 @@ static void ComputeTangency (const Contap_TheSearch& solrst,
                 const Contap_ThePathPointOfTheSearch& PStart2 = solrst.Point(k);
                 if (!PStart2.IsNew()) {
                   const Handle(Adaptor3d_HVertex)& vtx2 = PStart2.Vertex();
-                  if (Domain->Identical(vtx,vtx2)) {
+                  if (theDomain->Identical(vtx,vtx2)) {
                     const Handle(Adaptor2d_HCurve2d)& thearc2   = PStart2.Arc();
                     theparam = PStart2.Parameter();
-                    arcorien = Domain->Orientation(thearc2);
+                    arcorien = theDomain->Orientation(thearc2);
                     ispassing = ispassing && (arcorien == TopAbs_INTERNAL ||
                       arcorien == TopAbs_EXTERNAL);
 
@@ -648,7 +651,7 @@ static void ComputeTangency (const Contap_TheSearch& solrst,
                 arcorien != TopAbs_EXTERNAL) {
                   // pour essai
                   const Handle(Adaptor3d_HVertex)& vtx = PStart.Vertex();
-                  vtxorien = Domain->Orientation(vtx);
+                  vtxorien = theDomain->Orientation(vtx);
                   test = test/(vectg.Magnitude());
                   test = test/((normale.Crossed(tg3drst)).Magnitude());
 
@@ -675,10 +678,10 @@ static void ComputeTangency (const Contap_TheSearch& solrst,
                   const Contap_ThePathPointOfTheSearch& PStart2 = solrst.Point(k);
                   if (!PStart2.IsNew()) {
                     const Handle(Adaptor3d_HVertex)& vtx2 = PStart2.Vertex();
-                    if (Domain->Identical(PStart.Vertex(),vtx2)) {
+                    if (theDomain->Identical(PStart.Vertex(),vtx2)) {
                       const Handle(Adaptor2d_HCurve2d)& thearc2 = PStart2.Arc();
                       theparam = PStart2.Parameter();
-                      arcorien = Domain->Orientation(thearc2);
+                      arcorien = theDomain->Orientation(thearc2);
 
                       Contap_HCurve2dTool::D1(thearc2,theparam,pt2d,tg2drst);
                       X(1) = pt2d.X();
@@ -693,7 +696,7 @@ static void ComputeTangency (const Contap_TheSearch& solrst,
                           test = test/(vectg.Magnitude());
                           test = test /((normale.Crossed(tg3drst)).Magnitude());
 
-                          vtxorien = Domain->Orientation(vtx2);
+                          vtxorien = theDomain->Orientation(vtx2);
                           if (Abs(test) <= tole) {
                             tobeverified = Standard_True;
                             LocTrans = TopAbs_EXTERNAL; // et pourquoi pas INTERNAL
@@ -746,13 +749,13 @@ static void ComputeTangency (const Contap_TheSearch& solrst,
                   if (Destination(k)==seqlength + 1) {
                     theparam = solrst.Point(k).Parameter();
                     const Handle(Adaptor2d_HCurve2d)& thearc2 = solrst.Point(k).Arc();
-                    arcorien = Domain->Orientation(thearc2);
+                    arcorien = theDomain->Orientation(thearc2);
 
                     if (arcorien == TopAbs_FORWARD ||
                       arcorien == TopAbs_REVERSED) {
                         Contap_HCurve2dTool::D1(thearc2,theparam,pt2d,tg2drst);
                         tg3drst = tg2drst.X()*v1 + tg2drst.Y()*v2;
-                        vtxorien = Domain->Orientation(solrst.Point(k).Vertex());
+                        vtxorien = theDomain->Orientation(solrst.Point(k).Vertex());
                         if ((arcorien == TopAbs_FORWARD && 
                           vtxorien == TopAbs_REVERSED)    ||
                           (arcorien == TopAbs_REVERSED &&
@@ -858,7 +861,7 @@ void ProcessSegments (const Contap_TheSearch& solrst,
                       Contap_TheSequenceOfLine& slin,
                       const Standard_Real TolArc,
                       Contap_SurfFunction& SFunc,
-                      const Handle(Adaptor3d_TopolTool)& Domain)
+                      const Handle(Adaptor3d_TopolTool)& theDomain)
 
 {     
   Standard_Integer i,j,k;
@@ -992,7 +995,7 @@ void ProcessSegments (const Contap_TheSearch& solrst,
     if (thesegsol.HasFirstPoint() && thesegsol.HasLastPoint()) {
       ComputeInternalPointsOnRstr(theline,paramf,paraml,SFunc);
     }
-    LineConstructor(slin,Domain,theline,SFunc.Surface()); //-- lbr 
+    LineConstructor(slin,theDomain,theline,SFunc.Surface()); //-- lbr 
     //-- slin.Append(theline);
     theline.Clear();
   }
@@ -1364,8 +1367,8 @@ void ComputeInternalPoints
 }
 
 
-void Contap_Contour::Perform 
-(const Handle(Adaptor3d_TopolTool)& Domain) {
+void Contap_Contour::Perform(const Handle(Adaptor3d_TopolTool)& theDomain)
+{
 
   done = Standard_False;
   slin.Clear();
@@ -1444,7 +1447,7 @@ void Contap_Contour::Perform
   mySFunc.Set(Precision::Confusion()); // tolerance sur la fonction
 
   Standard_Boolean RecheckOnRegularity = Standard_True;
-  solrst.Perform(myAFunc,Domain,TolArc,TolArc,RecheckOnRegularity);
+  solrst.Perform(myAFunc,theDomain,TolArc,TolArc,RecheckOnRegularity);
 
   if (!solrst.IsDone()) {
     return;
@@ -1455,11 +1458,11 @@ void Contap_Contour::Perform
   TColStd_Array1OfInteger Destination(1,NbPointRst+1);
   Destination.Init(0);
   if (NbPointRst != 0) {
-    ComputeTangency(solrst,Domain,mySFunc,seqpdep,Destination);
+    ComputeTangency(solrst,theDomain,mySFunc,seqpdep,Destination);
   }
 
   //jag 940616  solins.Perform(SFunc,Surf,Domain,1.e-6); // 1.e-6 : tolerance dans l espace.
-  solins.Perform(mySFunc,Surf,Domain,Precision::Confusion());
+  solins.Perform(mySFunc,Surf,theDomain,Precision::Confusion());
 
   NbPointIns = solins.NbPoints();
   IntSurf_SequenceOfInteriorPoint seqpins;
@@ -1618,7 +1621,7 @@ void Contap_Contour::Perform
       }
 
       ComputeInternalPoints(theline,mySFunc,EpsU,EpsV);
-      LineConstructor(slin,Domain,theline,Surf); //-- lbr
+      LineConstructor(slin,theDomain,theline,Surf); //-- lbr
       //-- slin.Append(theline);
       theline.ResetSeqOfVertex();
     }
@@ -1654,7 +1657,7 @@ void Contap_Contour::Perform
   // jag 940620 On ajoute le traitement des restrictions solutions.
 
   if (solrst.NbSegments() !=0) {
-    ProcessSegments(solrst,slin,TolArc,mySFunc,Domain);
+    ProcessSegments(solrst,slin,TolArc,mySFunc,theDomain);
   }
 
 
@@ -1918,7 +1921,7 @@ IntSurf_TypeTrans ComputeTransitionOngpCircle
 }
 
 
-void Contap_Contour::PerformAna(const Handle(Adaptor3d_TopolTool)& Domain)
+void Contap_Contour::PerformAna(const Handle(Adaptor3d_TopolTool)& theDomain)
 {
 
   done = Standard_False;
@@ -2114,7 +2117,7 @@ void Contap_Contour::PerformAna(const Handle(Adaptor3d_TopolTool)& Domain)
 
   if(PerformSolRst) { 
 
-    solrst.Perform(myAFunc,Domain,TolArc,TolArc);
+    solrst.Perform(myAFunc,theDomain,TolArc,TolArc);
     if (!solrst.IsDone()) {
       return;
     }
@@ -2125,7 +2128,7 @@ void Contap_Contour::PerformAna(const Handle(Adaptor3d_TopolTool)& Domain)
     }
 
     if (solrst.NbSegments() !=0) {
-      ProcessSegments(solrst,slin,TolArc,mySFunc,Domain);
+      ProcessSegments(solrst,slin,TolArc,mySFunc,theDomain);
     }
 
 
@@ -2139,7 +2142,7 @@ void Contap_Contour::PerformAna(const Handle(Adaptor3d_TopolTool)& Domain)
       //-- cout<<" nbvtx : "<<slin.Value(i).NbVertex()<<endl;
       //--if(slin.Value(i).NbVertex() > 1) { 
       if(slin.Value(i).TypeContour() != Contap_Restriction) { 
-        LineConstructor(slin,Domain,slin.ChangeValue(i),Surf);
+        LineConstructor(slin,theDomain,slin.ChangeValue(i),Surf);
         SeqToDestroy.Append(i);
       }
       //-- }
diff --git a/src/Contap/Contap_Contour.hxx b/src/Contap/Contap_Contour.hxx
index d888a45..ec3ae6d 100644
--- a/src/Contap/Contap_Contour.hxx
+++ b/src/Contap/Contap_Contour.hxx
@@ -102,16 +102,15 @@ public:
 
 protected:
 
-
+  Standard_EXPORT void Perform (const Handle(Adaptor3d_TopolTool)& Domain);
+  
+  Standard_EXPORT void PerformAna (const Handle(Adaptor3d_TopolTool)& Domain);
 
 
 
 private:
 
   
-  Standard_EXPORT void Perform (const Handle(Adaptor3d_TopolTool)& Domain);
-  
-  Standard_EXPORT void PerformAna (const Handle(Adaptor3d_TopolTool)& Domain);
 
 
   Standard_Boolean done;
diff --git a/src/DsgPrs/DsgPrs_ShapeDirPresentation.cxx b/src/DsgPrs/DsgPrs_ShapeDirPresentation.cxx
index b86ed2c..007a5d6 100644
--- a/src/DsgPrs/DsgPrs_ShapeDirPresentation.cxx
+++ b/src/DsgPrs/DsgPrs_ShapeDirPresentation.cxx
@@ -18,7 +18,6 @@
 #include <Bnd_Box.hxx>
 #include <BRep_Tool.hxx>
 #include <BRepBndLib.hxx>
-#include <BRepClass_Edge.hxx>
 #include <BRepClass_FaceClassifier.hxx>
 #include <BRepTools_WireExplorer.hxx>
 #include <DsgPrs_ShapeDirPresentation.hxx>
diff --git a/src/Geom2dHatch/Geom2dHatch_Classifier.hxx b/src/Geom2dHatch/Geom2dHatch_Classifier.hxx
index 025c184..876cdaa 100644
--- a/src/Geom2dHatch/Geom2dHatch_Classifier.hxx
+++ b/src/Geom2dHatch/Geom2dHatch_Classifier.hxx
@@ -19,113 +19,46 @@
 
 #include <Standard.hxx>
 #include <Standard_DefineAlloc.hxx>
-#include <Standard_Handle.hxx>
 
-#include <Geom2dHatch_FClass2dOfClassifier.hxx>
-#include <Geom2dAdaptor_Curve.hxx>
-#include <Standard_Real.hxx>
 #include <IntRes2d_Position.hxx>
-#include <Standard_Boolean.hxx>
 #include <TopAbs_State.hxx>
-class Standard_DomainError;
+#include <TopClass_GeomEdge.hxx>
+
 class Geom2dHatch_Elements;
-class Geom2dAdaptor_Curve;
-class Geom2dHatch_Intersector;
-class Geom2dHatch_FClass2dOfClassifier;
 class gp_Pnt2d;
 
-
-
 class Geom2dHatch_Classifier 
 {
 public:
 
   DEFINE_STANDARD_ALLOC
 
-  
+
   //! Empty constructor, undefined algorithm.
   Standard_EXPORT Geom2dHatch_Classifier();
-  
-  //! Creates an algorithm to classify the Point  P with
-  //! Tolerance <T> on the face described by <F>.
-  Standard_EXPORT Geom2dHatch_Classifier(Geom2dHatch_Elements& F, const gp_Pnt2d& P, const Standard_Real Tol);
-  
-  //! Classify  the Point  P  with  Tolerance <T> on the
-  //! face described by <F>.
-  Standard_EXPORT void Perform (Geom2dHatch_Elements& F, const gp_Pnt2d& P, const Standard_Real Tol);
-  
-  //! Returns the result of the classification.
-  Standard_EXPORT TopAbs_State State() const;
-  
-  //! Returns  True when  the   state was computed by  a
-  //! rejection. The state is OUT.
-    Standard_Boolean Rejected() const;
-  
-  //! Returns True if  the face  contains  no wire.  The
-  //! state is IN.
-    Standard_Boolean NoWires() const;
-  
-  //! Returns   the    Edge  used   to    determine  the
-  //! classification. When the State is ON  this  is the
-  //! Edge containing the point.
-  Standard_EXPORT const Geom2dAdaptor_Curve& Edge() const;
-  
-  //! Returns the parameter on Edge() used to determine  the
-  //! classification.
-  Standard_EXPORT Standard_Real EdgeParameter() const;
-  
-  //! Returns the  position of  the   point on the  edge
-  //! returned by Edge.
-    IntRes2d_Position Position() const;
-
 
+  //! Classify the Point P with 2D-tolerance <theTol2D> relatively to
+  //! the contour set by the 2D-curves in <F>.
+  Standard_EXPORT void Perform(Geom2dHatch_Elements& F,
+                               const gp_Pnt2d& P,
+                               const Standard_Real theTol2D);
 
+  //! Returns the result of the classification.
+  Standard_EXPORT TopAbs_State State() const;
 
 protected:
 
 
-
-  Geom2dHatch_FClass2dOfClassifier myClassifier;
-  Geom2dAdaptor_Curve myEdge;
-  Standard_Real myEdgeParameter;
-  IntRes2d_Position myPosition;
-  Standard_Boolean rejected;
-  Standard_Boolean nowires;
-
-
 private:
 
+  //! ATTENTION!!!
+  //! Fields myEdge and myEdgeParameter
+  //! should be eliminated after removing TopOpeBRep*
+  //! packages.
 
-
-
-
+  TopClass_GeomEdge myEdge;
+  Standard_Real myEdgeParameter;
+  TopAbs_State myState;
 };
 
-#define TheFaceExplorer Geom2dHatch_Elements
-#define TheFaceExplorer_hxx <Geom2dHatch_Elements.hxx>
-#define TheEdge Geom2dAdaptor_Curve
-#define TheEdge_hxx <Geom2dAdaptor_Curve.hxx>
-#define TheIntersection2d Geom2dHatch_Intersector
-#define TheIntersection2d_hxx <Geom2dHatch_Intersector.hxx>
-#define TopClass_FClass2d Geom2dHatch_FClass2dOfClassifier
-#define TopClass_FClass2d_hxx <Geom2dHatch_FClass2dOfClassifier.hxx>
-#define TopClass_FaceClassifier Geom2dHatch_Classifier
-#define TopClass_FaceClassifier_hxx <Geom2dHatch_Classifier.hxx>
-
-#include <TopClass_FaceClassifier.lxx>
-
-#undef TheFaceExplorer
-#undef TheFaceExplorer_hxx
-#undef TheEdge
-#undef TheEdge_hxx
-#undef TheIntersection2d
-#undef TheIntersection2d_hxx
-#undef TopClass_FClass2d
-#undef TopClass_FClass2d_hxx
-#undef TopClass_FaceClassifier
-#undef TopClass_FaceClassifier_hxx
-
-
-
-
 #endif // _Geom2dHatch_Classifier_HeaderFile
diff --git a/src/Geom2dHatch/Geom2dHatch_Classifier_0.cxx b/src/Geom2dHatch/Geom2dHatch_Classifier_0.cxx
index 431f1d8..8811a39 100644
--- a/src/Geom2dHatch/Geom2dHatch_Classifier_0.cxx
+++ b/src/Geom2dHatch/Geom2dHatch_Classifier_0.cxx
@@ -26,8 +26,12 @@
 
 #define TheFaceExplorer Geom2dHatch_Elements
 #define TheFaceExplorer_hxx <Geom2dHatch_Elements.hxx>
-#define TheEdge Geom2dAdaptor_Curve
-#define TheEdge_hxx <Geom2dAdaptor_Curve.hxx>
+
+//! Are used only for compatibility with TopOpeBRep
+//! packages. It should be deleted after this package will be eliminated.
+#define TheTopoEdge Geom2dAdaptor_Curve
+#define TheTopoEdge_hxx <Geom2dAdaptor_Curve.hxx>
+
 #define TheIntersection2d Geom2dHatch_Intersector
 #define TheIntersection2d_hxx <Geom2dHatch_Intersector.hxx>
 #define TopClass_FClass2d Geom2dHatch_FClass2dOfClassifier
diff --git a/src/Geom2dHatch/Geom2dHatch_Elements.cxx b/src/Geom2dHatch/Geom2dHatch_Elements.cxx
index d487ee7..41a42dd 100644
--- a/src/Geom2dHatch/Geom2dHatch_Elements.cxx
+++ b/src/Geom2dHatch/Geom2dHatch_Elements.cxx
@@ -1,4 +1,4 @@
-// Created on: 1994-12-16
+﻿// Created on: 1994-12-16
 // Created by: Laurent BUCHARD
 // Copyright (c) 1994-1999 Matra Datavision
 // Copyright (c) 1999-2014 OPEN CASCADE SAS
@@ -16,31 +16,22 @@
 
 //  Modified by skv - Fri Jul 14 17:03:47 2006 OCC12627
 
-#include <Geom2dAdaptor_Curve.hxx>
-#include <Geom2dHatch_Element.hxx>
 #include <Geom2dHatch_Elements.hxx>
-#include <gp.hxx>
-#include <gp_Lin2d.hxx>
-#include <gp_Pnt2d.hxx>
-#include <gp_Vec2d.hxx>
-#include <Standard_DomainError.hxx>
-#include <Standard_Integer.hxx>
-#include <Standard_NoSuchObject.hxx>
-#include <TColStd_MapIntegerHasher.hxx>
-#include <TopAbs_Orientation.hxx>
-
-Geom2dHatch_Elements::Geom2dHatch_Elements(const Geom2dHatch_Elements& )
+
+#include <TopClass_GeomEdge.hxx>
+#include <TopClass_RayInfo.hxx>
+
+Geom2dHatch_Elements::
+  Geom2dHatch_Elements(const Geom2dHatch_Elements&) :myCurrentWire(0),
+                                                     myCurEdge(0)
 {
 #ifdef OCCT_DEBUG
   cout<<" Magic Constructor in Geom2dHatch_Elements:: "<<endl;
 #endif
 }
 
-Geom2dHatch_Elements::Geom2dHatch_Elements()
+Geom2dHatch_Elements::Geom2dHatch_Elements() :myCurrentWire(0)
 {
-  NumWire = 0;
-  NumEdge = 0;
-  myCurEdge = 1;
 }
 
 void Geom2dHatch_Elements::Clear()
@@ -84,65 +75,51 @@ Standard_Boolean  Geom2dHatch_Elements::CheckPoint(gp_Pnt2d&)
 }
 
 //=======================================================================
-//function : Reject
-//purpose  : 
-//=======================================================================
-
-Standard_Boolean  Geom2dHatch_Elements::Reject(const gp_Pnt2d&) const  {
-  return Standard_False;
-}
-
-//=======================================================================
-//function : Segment
-//purpose  : 
+//function : OtherRay
+//purpose  : theMaxRating is kept for compatibility with analogical
+//            method in BRepClass_FaceExplorer.
 //=======================================================================
-
-Standard_Boolean Geom2dHatch_Elements::Segment(const gp_Pnt2d& P, 
-					             gp_Lin2d& L, 
-					             Standard_Real& Par)
+Standard_Boolean Geom2dHatch_Elements::OtherRay(const gp_Pnt2d& thePnt,
+                                                TopClass_RayInfo& theRay,
+                                                const unsigned int /*theMaxRating*/)
 {
-  myCurEdge = 1;
-
-  return OtherSegment(P, L, Par);
-}
-
-//=======================================================================
-//function : Segment
-//purpose  : 
-//=======================================================================
-
-Standard_Boolean Geom2dHatch_Elements::OtherSegment(const gp_Pnt2d& P, 
-						          gp_Lin2d& L, 
-						          Standard_Real& Par)
-{
-  Geom2dHatch_DataMapIteratorOfMapOfElements Itertemp;
-  Standard_Integer                        i;
-  
-  for(  Itertemp.Initialize(myMap), i = 1; Itertemp.More(); Itertemp.Next(), i++) { 
+  Geom2dHatch_DataMapIteratorOfMapOfElements Itertemp(myMap);
+  Standard_Integer i = 1;
+  for (; Itertemp.More(); Itertemp.Next(), i++)
+  {
     if (i < myCurEdge)
       continue;
 
-    void *ptrmyMap = (void *)(&myMap);
-    Geom2dHatch_Element& Item=((Geom2dHatch_MapOfElements*)ptrmyMap)->ChangeFind(Itertemp.Key());
-    Geom2dAdaptor_Curve& E = Item.ChangeCurve();
-    TopAbs_Orientation Or= Item.Orientation();
-    gp_Pnt2d P2 = E.Value
-      ((E.FirstParameter() + E.LastParameter()) *0.5);
-    if ((Or == TopAbs_FORWARD) ||
-	(Or == TopAbs_REVERSED)) {
-      gp_Vec2d V(P,P2);
-      Par = V.Magnitude();
-      if (Par >= gp::Resolution()) {
-	L = gp_Lin2d(P,V);
-	myCurEdge++;
-	return Standard_True;
-      }
+    const Standard_Integer anIdx = Itertemp.Key();
+    const Geom2dHatch_Element& anItem = myMap.Find(anIdx);
+    const Geom2dAdaptor_Curve& E = anItem.Curve();
+    const TopAbs_Orientation anOri = anItem.Orientation();
+    if ((anOri != TopAbs_FORWARD) && (anOri != TopAbs_REVERSED))
+    {
+      myCurEdge++;
+      continue;
+    }
+
+    TopClass_RayInfo aRI;
+    const gp_Pnt2d aPE = E.Value((E.FirstParameter() + E.LastParameter()) *0.5);
+    const gp_Vec2d aV(thePnt, aPE);
+    aRI.SetParameter(aV.Magnitude());
+    if (aRI.GetParameter() < gp::Resolution())
+    {
+      myCurEdge++;
+      continue;
     }
+
+    aRI.SetLin(gp_Lin2d(thePnt, aV));
+    theRay = aRI;
+    myCurEdge++;
+    return Standard_True;
   }
 
-  if (i == myCurEdge + 1) {
-    Par = RealLast();
-    L = gp_Lin2d(P,gp_Dir2d(1,0));
+  if (i == myCurEdge + 1)
+  {
+    theRay.SetParameter(RealLast());
+    theRay.SetLin(gp_Lin2d(thePnt, gp_Dir2d(1, 0)));
     myCurEdge++;
 
     return Standard_True;
@@ -156,19 +133,9 @@ Standard_Boolean Geom2dHatch_Elements::OtherSegment(const gp_Pnt2d& P,
 //purpose  : 
 //=======================================================================
 
-void  Geom2dHatch_Elements::InitWires()  {
-  NumWire = 0;
-}
-
-//=======================================================================
-//function : RejectWire NYI
-//purpose  : 
-//=======================================================================
-
-Standard_Boolean Geom2dHatch_Elements::RejectWire(const gp_Lin2d& , 
-						   const Standard_Real) const 
+void  Geom2dHatch_Elements::InitWires()
 {
-  return Standard_False;
+  myCurrentWire = 0;
 }
 
 //=======================================================================
@@ -176,41 +143,20 @@ Standard_Boolean Geom2dHatch_Elements::RejectWire(const gp_Lin2d& ,
 //purpose  : 
 //=======================================================================
 
-void  Geom2dHatch_Elements::InitEdges()  {
-  NumEdge = 0;
-  Iter.Initialize(myMap);
-}
-
-//=======================================================================
-//function : RejectEdge NYI
-//purpose  : 
-//=======================================================================
-
-Standard_Boolean Geom2dHatch_Elements::RejectEdge(const gp_Lin2d& , 
-						  const Standard_Real ) const 
+void  Geom2dHatch_Elements::InitEdges()
 {
-  return Standard_False;
+  myIter.Initialize(myMap);
 }
 
-
 //=======================================================================
 //function : CurrentEdge
 //purpose  : 
 //=======================================================================
 
-void  Geom2dHatch_Elements::CurrentEdge(Geom2dAdaptor_Curve& E, 
-					TopAbs_Orientation& Or) const 
+void  Geom2dHatch_Elements::CurrentEdge(TopClass_GeomEdge& theGE) const 
 {
-  void *ptrmyMap = (void *)(&myMap);
-  Geom2dHatch_Element& Item=((Geom2dHatch_MapOfElements*)ptrmyMap)->ChangeFind(Iter.Key());
-
-  E = Item.ChangeCurve();
-  Or= Item.Orientation();
-#if 0 
-  E.Edge() = TopoDS::Edge(myEExplorer.Current());
-  E.Face() = myFace;
-  Or = E.Edge().Orientation();
-#endif
+  const Geom2dHatch_Element& anItem = myMap.Find(myIter.Key());
+  theGE.Replace2DCurve(anItem.Curve(), anItem.Orientation());
 }
 
 
@@ -221,7 +167,7 @@ void  Geom2dHatch_Elements::CurrentEdge(Geom2dAdaptor_Curve& E,
 
 Standard_Boolean  Geom2dHatch_Elements::MoreWires() const 
 {
-  return (NumWire == 0);
+  return (myCurrentWire == 0);
 }
 
 //=======================================================================
@@ -229,8 +175,9 @@ Standard_Boolean  Geom2dHatch_Elements::MoreWires() const
 //purpose  : 
 //=======================================================================
 
-void Geom2dHatch_Elements::NextWire()  {
-  NumWire++;
+void Geom2dHatch_Elements::NextWire()
+{
+  myCurrentWire++;
 }
 
 //=======================================================================
@@ -238,8 +185,9 @@ void Geom2dHatch_Elements::NextWire()  {
 //purpose  : 
 //=======================================================================
 
-Standard_Boolean  Geom2dHatch_Elements::MoreEdges() const  {
-  return(Iter.More());
+Standard_Boolean  Geom2dHatch_Elements::MoreEdges() const
+{
+  return(myIter.More());
 }
 
 //=======================================================================
@@ -247,9 +195,44 @@ Standard_Boolean  Geom2dHatch_Elements::MoreEdges() const  {
 //purpose  : 
 //=======================================================================
 
-void Geom2dHatch_Elements::NextEdge()  {
-  Iter.Next();
+void Geom2dHatch_Elements::NextEdge()
+{
+  myIter.Next();
 }
 
+//=======================================================================
+//function : IsPointInEdgeVertex
+//purpose  : 
+//=======================================================================
+Standard_Boolean
+  Geom2dHatch_Elements::IsPointInEdgeVertex(const gp_Pnt2d &thePnt,
+                                            Standard_Real* const theParameter) const
+{
+  const Geom2dAdaptor_Curve& aCurv = myMap.Find(myIter.Key()).Curve();
+  const gp_Pnt2d aPntF(aCurv.Value(aCurv.FirstParameter())),
+                 aPntL(aCurv.Value(aCurv.LastParameter()));
+  const Standard_Real aSqTol = Precision::SquarePConfusion();
+
+  if (thePnt.SquareDistance(aPntF) < aSqTol)
+  {
+    if (theParameter)
+      *theParameter = aCurv.FirstParameter();
+
+    return Standard_True;
+  }
+
+  if (thePnt.SquareDistance(aPntL) < aSqTol)
+  {
+    if (theParameter)
+      *theParameter = aCurv.LastParameter();
+
+    return Standard_True;
+  }
+
+  if (theParameter)
+    *theParameter = 0.0;
+
+  return Standard_False;
+}
 
 
diff --git a/src/Geom2dHatch/Geom2dHatch_Elements.hxx b/src/Geom2dHatch/Geom2dHatch_Elements.hxx
index 5ef0623..7b0b9d0 100644
--- a/src/Geom2dHatch/Geom2dHatch_Elements.hxx
+++ b/src/Geom2dHatch/Geom2dHatch_Elements.hxx
@@ -17,24 +17,11 @@
 #ifndef _Geom2dHatch_Elements_HeaderFile
 #define _Geom2dHatch_Elements_HeaderFile
 
-#include <Standard.hxx>
-#include <Standard_DefineAlloc.hxx>
-#include <Standard_Handle.hxx>
-
 #include <Geom2dHatch_MapOfElements.hxx>
-#include <Geom2dHatch_DataMapIteratorOfMapOfElements.hxx>
-#include <Standard_Integer.hxx>
-#include <Standard_Boolean.hxx>
-#include <Standard_Real.hxx>
-#include <TopAbs_Orientation.hxx>
-class Standard_DomainError;
-class Standard_NoSuchObject;
-class Geom2dHatch_Element;
-class gp_Pnt2d;
-class gp_Lin2d;
-class Geom2dAdaptor_Curve;
-
+#include <NCollection_List.hxx>
 
+class TopClass_GeomEdge;
+class TopClass_RayInfo;
 
 class Geom2dHatch_Elements 
 {
@@ -48,80 +35,84 @@ public:
   Standard_EXPORT Geom2dHatch_Elements(const Geom2dHatch_Elements& Other);
   
   Standard_EXPORT void Clear();
-~Geom2dHatch_Elements()
-{
-  Clear();
-}
+  ~Geom2dHatch_Elements()
+  {
+    Clear();
+  }
   
-  Standard_EXPORT Standard_Boolean Bind (const Standard_Integer K, const Geom2dHatch_Element& I);
+  Standard_EXPORT Standard_Boolean Bind (const Standard_Integer K,
+                                         const Geom2dHatch_Element& I);
   
   Standard_EXPORT Standard_Boolean IsBound (const Standard_Integer K) const;
   
   Standard_EXPORT Standard_Boolean UnBind (const Standard_Integer K);
   
-  Standard_EXPORT const Geom2dHatch_Element& Find (const Standard_Integer K) const;
-const Geom2dHatch_Element& operator() (const Standard_Integer K) const
-{
-  return Find(K);
-}
+  Standard_EXPORT const Geom2dHatch_Element& Find(const Standard_Integer K) const;
+  const Geom2dHatch_Element& operator() (const Standard_Integer K) const
+  {
+    return Find(K);
+  }
   
-  Standard_EXPORT Geom2dHatch_Element& ChangeFind (const Standard_Integer K);
-Geom2dHatch_Element& operator() (const Standard_Integer K)
-{
-  return ChangeFind(K);
-}
+  Standard_EXPORT Geom2dHatch_Element& ChangeFind(const Standard_Integer K);
+  Geom2dHatch_Element& operator() (const Standard_Integer K)
+  {
+    return ChangeFind(K);
+  }
+
+  //! This function is entered only for compatibility with BRepClass*.
   Standard_EXPORT Standard_Boolean CheckPoint (gp_Pnt2d& P);
 
-  Standard_EXPORT Standard_Boolean Reject (const gp_Pnt2d& P) const;
-  
-  Standard_EXPORT Standard_Boolean Segment (const gp_Pnt2d& P, gp_Lin2d& L, Standard_Real& Par);
-  
-  Standard_EXPORT Standard_Boolean OtherSegment (const gp_Pnt2d& P, gp_Lin2d& L, Standard_Real& Par);
-  
+  //! Returns ray to process.
+  //! theMaxRating variable is entered for compatibility with
+  //! BRepClass* classes and is not use here.
+  Standard_EXPORT Standard_Boolean OtherRay(const gp_Pnt2d& thePnt,
+                                            TopClass_RayInfo& theRay,
+                                            const unsigned int theMaxRating);
+
   Standard_EXPORT void InitWires();
   
   Standard_EXPORT Standard_Boolean MoreWires() const;
   
   Standard_EXPORT void NextWire();
   
-  Standard_EXPORT Standard_Boolean RejectWire (const gp_Lin2d& L, const Standard_Real Par) const;
-  
   Standard_EXPORT void InitEdges();
   
   Standard_EXPORT Standard_Boolean MoreEdges() const;
   
   Standard_EXPORT void NextEdge();
   
-  Standard_EXPORT Standard_Boolean RejectEdge (const gp_Lin2d& L, const Standard_Real Par) const;
-  
-  Standard_EXPORT void CurrentEdge (Geom2dAdaptor_Curve& E, TopAbs_Orientation& Or) const;
-
-
+  //! Returns analyzed edge.
+  Standard_EXPORT void CurrentEdge(TopClass_GeomEdge& theGE) const;
 
+  //! Returns TRUE if thePnt is covered by the tolerance of at least one
+  //! vertex of the analyzed edge.
+  //! If is true then stores the parameter of the vertex on the curve.
+  //! Otherwise, returns *theParameter = 0.0.
+  //! This parameter is used in TopOpeBRep class
+  //! and must be deleted after this class will be eliminated.
+  Standard_EXPORT 
+    Standard_Boolean IsPointInEdgeVertex(const gp_Pnt2d &thePnt,
+                                         Standard_Real* const theParameter = 0) const;
 
-protected:
+  Standard_Boolean FirstRay(const gp_Pnt2d& theP,
+                            TopClass_RayInfo& theRay,
+                            const unsigned int theMaxRating = UINT_MAX)
+  {
+    myCurEdge = 1;
 
+    return OtherRay(theP, theRay, theMaxRating);
+  }
 
 
 
+protected:
+  
 
 private:
-
-
-
   Geom2dHatch_MapOfElements myMap;
-  Geom2dHatch_DataMapIteratorOfMapOfElements Iter;
-  Standard_Integer NumWire;
-  Standard_Integer NumEdge;
+  Geom2dHatch_DataMapIteratorOfMapOfElements myIter;
+  Standard_Integer myCurrentWire;
   Standard_Integer myCurEdge;
-
-
 };
 
-
-
-
-
-
-
 #endif // _Geom2dHatch_Elements_HeaderFile
diff --git a/src/Geom2dHatch/Geom2dHatch_FClass2dOfClassifier.hxx b/src/Geom2dHatch/Geom2dHatch_FClass2dOfClassifier.hxx
index f4e25ee..69e9315 100644
--- a/src/Geom2dHatch/Geom2dHatch_FClass2dOfClassifier.hxx
+++ b/src/Geom2dHatch/Geom2dHatch_FClass2dOfClassifier.hxx
@@ -17,24 +17,15 @@
 #ifndef _Geom2dHatch_FClass2dOfClassifier_HeaderFile
 #define _Geom2dHatch_FClass2dOfClassifier_HeaderFile
 
-#include <Standard.hxx>
 #include <Standard_DefineAlloc.hxx>
-#include <Standard_Handle.hxx>
 
-#include <Standard_Boolean.hxx>
-#include <gp_Lin2d.hxx>
-#include <Standard_Real.hxx>
-#include <TopTrans_CurveTransition.hxx>
 #include <Geom2dHatch_Intersector.hxx>
-#include <Standard_Integer.hxx>
-#include <TopAbs_State.hxx>
+#include <gp_Lin2d.hxx>
 #include <TopAbs_Orientation.hxx>
-class Standard_DomainError;
-class Geom2dAdaptor_Curve;
-class Geom2dHatch_Intersector;
-class gp_Lin2d;
-
+#include <TopAbs_State.hxx>
+#include <TopTrans_CurveTransition.hxx>
 
+class TopClass_GeomEdge;
 
 class Geom2dHatch_FClass2dOfClassifier 
 {
@@ -51,51 +42,44 @@ public:
   //! the original length of the segment on <L>  used to
   //! compute  intersections.   <Tol> is the   tolerance
   //! attached to the line segment in intersections.
-  Standard_EXPORT void Reset (const gp_Lin2d& L, const Standard_Real P, const Standard_Real Tol);
+  Standard_EXPORT void Reset (const gp_Lin2d& L, const Standard_Real P);
   
   //! Updates  the classification process with  the edge
   //! <E> from the boundary.
-  Standard_EXPORT void Compare (const Geom2dAdaptor_Curve& E, const TopAbs_Orientation Or);
+  //! theTol2D is 2D-tolerance using in intersector of theE with
+  //! the linear ray myLin
+  Standard_EXPORT void Compare(const TopClass_GeomEdge& theE,
+                               const Standard_Real theTol2D);
   
   //! Returns the current value of the parameter.
-    Standard_Real Parameter() const;
-  
+  Standard_Real Parameter() const;
+
   //! Returns the intersecting algorithm.
-    Geom2dHatch_Intersector& Intersector();
-  
+  Geom2dHatch_Intersector& Intersector();
+
   //! Returns  0  if  the   last  compared   edge had no
   //! relevant intersection.  Else returns  the index of
   //! this   intersection  in the    last   intersection
   //! algorithm.
-    Standard_Integer ClosestIntersection() const;
-  
+  Standard_Integer ClosestIntersection() const;
+
   //! Returns the current state of the point.
-    TopAbs_State State() const;
-  
+  TopAbs_State State() const;
+
   //! Returns the Standard_True if the closest intersection point
   //! represents head or end of the edge. Returns Standard_False
   //! otherwise.
-    Standard_Boolean IsHeadOrEnd() const;
-
-
-
+  Standard_Boolean IsHeadOrEnd() const;
 
 protected:
 
-
-
-
-
 private:
 
-
-
-  Standard_Boolean myIsSet;
   Standard_Boolean myFirstCompare;
   Standard_Boolean myFirstTrans;
   gp_Lin2d myLin;
   Standard_Real myParam;
-  Standard_Real myTolerance;
+
   TopTrans_CurveTransition myTrans;
   Geom2dHatch_Intersector myIntersector;
   Standard_Integer myClosest;
@@ -105,8 +89,6 @@ private:
 
 };
 
-#define TheEdge Geom2dAdaptor_Curve
-#define TheEdge_hxx <Geom2dAdaptor_Curve.hxx>
 #define TheIntersector Geom2dHatch_Intersector
 #define TheIntersector_hxx <Geom2dHatch_Intersector.hxx>
 #define TopClass_Classifier2d Geom2dHatch_FClass2dOfClassifier
@@ -114,8 +96,6 @@ private:
 
 #include <TopClass_Classifier2d.lxx>
 
-#undef TheEdge
-#undef TheEdge_hxx
 #undef TheIntersector
 #undef TheIntersector_hxx
 #undef TopClass_Classifier2d
diff --git a/src/Geom2dHatch/Geom2dHatch_FClass2dOfClassifier_0.cxx b/src/Geom2dHatch/Geom2dHatch_FClass2dOfClassifier_0.cxx
index ffb15c3..bcd71de 100644
--- a/src/Geom2dHatch/Geom2dHatch_FClass2dOfClassifier_0.cxx
+++ b/src/Geom2dHatch/Geom2dHatch_FClass2dOfClassifier_0.cxx
@@ -21,9 +21,6 @@
 #include <Geom2dHatch_Intersector.hxx>
 #include <gp_Lin2d.hxx>
  
-
-#define TheEdge Geom2dAdaptor_Curve
-#define TheEdge_hxx <Geom2dAdaptor_Curve.hxx>
 #define TheIntersector Geom2dHatch_Intersector
 #define TheIntersector_hxx <Geom2dHatch_Intersector.hxx>
 #define TopClass_Classifier2d Geom2dHatch_FClass2dOfClassifier
diff --git a/src/Geom2dHatch/Geom2dHatch_Hatcher.cxx b/src/Geom2dHatch/Geom2dHatch_Hatcher.cxx
index d27dc7e..959c6b2 100644
--- a/src/Geom2dHatch/Geom2dHatch_Hatcher.cxx
+++ b/src/Geom2dHatch/Geom2dHatch_Hatcher.cxx
@@ -21,6 +21,7 @@
 #include <Geom2dHatch_Hatcher.hxx>
 #include <Geom2dHatch_Hatching.hxx>
 #include <Geom2dHatch_Intersector.hxx>
+#include <GeomLib.hxx>
 #include <HatchGen_Domain.hxx>
 #include <HatchGen_Domains.hxx>
 #include <HatchGen_PointOnElement.hxx>
@@ -738,7 +739,8 @@ Standard_Boolean Geom2dHatch_Hatcher::Trim (const Standard_Integer IndH,
 //            IndH-th hatching.
 //=======================================================================
 
-Standard_Boolean Geom2dHatch_Hatcher::GlobalTransition (HatchGen_PointOnHatching& Point)
+Standard_Boolean 
+    Geom2dHatch_Hatcher::GlobalTransition (HatchGen_PointOnHatching& Point) const
 {
   TopAbs_State StateBefore = TopAbs_UNKNOWN ;
   TopAbs_State StateAfter  = TopAbs_UNKNOWN ;
@@ -751,7 +753,13 @@ Standard_Boolean Geom2dHatch_Hatcher::GlobalTransition (HatchGen_PointOnHatching
 
   const Geom2dAdaptor_Curve& CurveH = HatchingCurve (Point.Index()) ;
 
-  myIntersector.LocalGeometry(CurveH.Curve(), Point.Parameter(), Tangente2d, Normale2d, Courbure);
+  if(!GeomLib::LocalGeometry(CurveH.Curve(),
+                             Point.Parameter(),
+                             Tangente2d,
+                             Normale2d, Courbure))
+  {
+    return Standard_False;
+  }
 
   Tangente.SetCoord (Tangente2d.X(), Tangente2d.Y(), 0.0) ;
   if (Courbure < Precision::Confusion()) {
@@ -805,7 +813,14 @@ Standard_Boolean Geom2dHatch_Hatcher::GlobalTransition (HatchGen_PointOnHatching
 #endif
     Param = PntE.Parameter();
 
-    myIntersector.LocalGeometry(CurveE.Curve(), Param, Tangente2d, Normale2d, Courbure);
+    if(!GeomLib::LocalGeometry(CurveE.Curve(),
+                                  Param,
+                                  Tangente2d,
+                                  Normale2d,
+                                  Courbure))
+    {
+      return Standard_False;
+    }
 
 //-----------------------------------------------------------------------
 // Calcul de la transition locale. On suppose les relations suivantes :
@@ -972,7 +987,11 @@ void Geom2dHatch_Hatcher::ComputeDomains (const Standard_Integer IndH)
   if(NbPnt == 0)
   {
     //-- cout << "The hatching # " << setw(3) << IndH << " has to be classified" << endl ;
-    Geom2dHatch_Classifier Classifier(myElements,Hatching.ClassificationPoint(),0.0000001); 
+    Geom2dHatch_Classifier Classifier;
+    Classifier.Perform(myElements,
+                       Hatching.ClassificationPoint(),
+                       Precision::PConfusion());
+
     if(Classifier.State() == TopAbs_IN)
     { 
       HatchGen_Domain domain ;
diff --git a/src/Geom2dHatch/Geom2dHatch_Hatcher.hxx b/src/Geom2dHatch/Geom2dHatch_Hatcher.hxx
index cbef299..9ba30e7 100644
--- a/src/Geom2dHatch/Geom2dHatch_Hatcher.hxx
+++ b/src/Geom2dHatch/Geom2dHatch_Hatcher.hxx
@@ -195,7 +195,7 @@ private:
   
   //! Sets the global transition (the before and after
   //! states and segment extremities flags) of the point.
-  Standard_EXPORT Standard_Boolean GlobalTransition (HatchGen_PointOnHatching& Point);
+  Standard_EXPORT Standard_Boolean GlobalTransition (HatchGen_PointOnHatching& Point) const;
 
 
   Geom2dHatch_Intersector myIntersector;
diff --git a/src/Geom2dHatch/Geom2dHatch_Intersector.cxx b/src/Geom2dHatch/Geom2dHatch_Intersector.cxx
index 13622c0..e146a40 100644
--- a/src/Geom2dHatch/Geom2dHatch_Intersector.cxx
+++ b/src/Geom2dHatch/Geom2dHatch_Intersector.cxx
@@ -23,6 +23,7 @@
 #include <gp_Dir2d.hxx>
 #include <gp_Lin2d.hxx>
 #include <Precision.hxx>
+#include <TopClass_GeomEdge.hxx>
 
 //=======================================================================
 //function : Geom2dHatch_Intersector
@@ -39,63 +40,33 @@ myTangencyTolerance(0.0)
 //purpose  : 
 //=======================================================================
 
-void  Geom2dHatch_Intersector::Perform(const gp_Lin2d& L, 
-				       const Standard_Real P, 
-				       const Standard_Real Tol, 
-				       const Geom2dAdaptor_Curve& C)
+void  Geom2dHatch_Intersector::Perform(const gp_Lin2d& theLin, 
+                                       const Standard_Real thePar, 
+                                       const Standard_Real theTol2D,
+                                       const TopClass_GeomEdge& theGE)
 {
-  
-//Standard_Real pfbid,plbid;
+  const gp_Pnt2d &aPnt2D = theLin.Location();
   IntRes2d_Domain DL;
-  if(P!=RealLast()) 
-    DL.SetValues(L.Location(),0.,Tol,ElCLib::Value(P,L),P,Tol);
-  else 
-    DL.SetValues(L.Location(),0.,Tol,Standard_True);
-  
-  IntRes2d_Domain DE(C.Value(C.FirstParameter()),
-		     C.FirstParameter(),Precision::PIntersection(),
-		     C.Value(C.LastParameter()),
-		     C.LastParameter(),Precision::PIntersection());
-  
-  Handle(Geom2d_Line) GL= new Geom2d_Line(L);
-  Geom2dAdaptor_Curve CGA(GL);
-  void *ptrpoureviterlesproblemesdeconst = (void *)(&C);
-
-  Geom2dInt_GInter Inter(CGA,
-			 DL,
-			 *((Geom2dAdaptor_Curve *)ptrpoureviterlesproblemesdeconst),
-			 DE,
-			 Precision::PConfusion(),
-			 Precision::PIntersection());
-  this->SetValues(Inter);
-}
-
-//=======================================================================
-//function : LocalGeometry
-//purpose  : 
-//=======================================================================
-
-void  Geom2dHatch_Intersector::LocalGeometry(const Geom2dAdaptor_Curve& E, 
-					     const Standard_Real U, 
-					     gp_Dir2d& Tang, 
-					     gp_Dir2d& Norm, 
-					     Standard_Real& C) const 
-{
-  //Standard_Real f,l;
-  Geom2dLProp_CLProps2d Prop(E.Curve(),U,2,Precision::PConfusion());
-
-  if(!Prop.IsTangentDefined()) return;
-
-  Prop.Tangent(Tang);
-  C = Prop.Curvature();
-  if (C > Precision::PConfusion() && C<RealLast())
-    Prop.Normal(Norm);
+  if(thePar != RealLast())
+    DL.SetValues(aPnt2D, 0., theTol2D, ElCLib::Value(thePar, theLin), thePar, theTol2D);
   else
-    Norm.SetCoord(Tang.Y(),-Tang.X());
-}
-
-
+    DL.SetValues(aPnt2D, 0., theTol2D, Standard_True);
 
+  const Geom2dAdaptor_Curve &anAC = theGE.Get2DCurve();
 
+  IntRes2d_Domain DE(anAC.Value(anAC.FirstParameter()),
+                     anAC.FirstParameter(), Precision::PIntersection(),
+                     anAC.Value(anAC.LastParameter()),
+                     anAC.LastParameter(), Precision::PIntersection());
 
+  Handle(Geom2d_Line) GL = new Geom2d_Line(theLin);
+  Geom2dAdaptor_Curve CGA(GL);
 
+  Geom2dInt_GInter Inter(CGA,
+                         DL,
+                         anAC,
+                         DE,
+                         Precision::PConfusion(),
+                         Precision::PIntersection());
+  this->SetValues(Inter);
+}
diff --git a/src/Geom2dHatch/Geom2dHatch_Intersector.hxx b/src/Geom2dHatch/Geom2dHatch_Intersector.hxx
index c3968d0..69e963f 100644
--- a/src/Geom2dHatch/Geom2dHatch_Intersector.hxx
+++ b/src/Geom2dHatch/Geom2dHatch_Intersector.hxx
@@ -17,17 +17,11 @@
 #ifndef _Geom2dHatch_Intersector_HeaderFile
 #define _Geom2dHatch_Intersector_HeaderFile
 
-#include <Standard.hxx>
-#include <Standard_DefineAlloc.hxx>
-#include <Standard_Handle.hxx>
-
-#include <Standard_Real.hxx>
 #include <Geom2dInt_GInter.hxx>
+
 class Geom2dAdaptor_Curve;
 class gp_Lin2d;
-class gp_Dir2d;
-
-
+class TopClass_GeomEdge;
 
 class Geom2dHatch_Intersector  : public Geom2dInt_GInter
 {
@@ -61,33 +55,21 @@ public:
   
   Standard_EXPORT Geom2dHatch_Intersector();
   
-  //! Performs the intersection   between the  2d   line
-  //! segment (<L>, <P>) and  the  Curve <E>.  The  line
-  //! segment  is the  part  of  the  2d   line   <L> of
-  //! parameter range [0, <P>] (P is positive and can be
-  //! RealLast()). Tol is the  Tolerance on the segment.
-  //! The order  is relevant, the  first argument is the
-  //! segment, the second the Edge.
-  Standard_EXPORT void Perform (const gp_Lin2d& L, const Standard_Real P, const Standard_Real Tol, const Geom2dAdaptor_Curve& E);
+  //! Performs the intersection between the 2d line
+  //! segment (<theLin>, <thePar>) and the Curve <theGE>.
+  //! The line segment is the part of the 2d line <theLin> of
+  //! parameter range [0, <thePar>] (thePar is positive and can be
+  //! RealLast()). theTol2D is the Tolerance on the segment.
+  //! The order is relevant, the first argument is the
+  //! segment, the second one is the Edge.
+  Standard_EXPORT void Perform(const gp_Lin2d& theLin,
+                               const Standard_Real thePar,
+                               const Standard_Real theTol2D,
+                               const TopClass_GeomEdge& theGE);
   
-  //! Returns in <T>,  <N> and <C>  the tangent,  normal
-  //! and  curvature of the edge  <E> at parameter value
-  //! <U>.
-  Standard_EXPORT void LocalGeometry (const Geom2dAdaptor_Curve& E, const Standard_Real U, gp_Dir2d& T, gp_Dir2d& N, Standard_Real& C) const;
-
-
-
-
 protected:
-
-
-
-
-
+  
 private:
-
-
-
   Standard_Real myConfusionTolerance;
   Standard_Real myTangencyTolerance;
 
diff --git a/src/GeomInt/GeomInt_IntSS.cxx b/src/GeomInt/GeomInt_IntSS.cxx
index 0e2d7c9..ecea88b 100644
--- a/src/GeomInt/GeomInt_IntSS.cxx
+++ b/src/GeomInt/GeomInt_IntSS.cxx
@@ -76,9 +76,9 @@ void GeomInt_IntSS::Perform(const Handle(Geom_Surface)& S1,
   myTolReached2d = myTolReached3d = 0.0;
   myNbrestr = 0;
   sline.Clear();
-  Handle(Adaptor3d_TopolTool) dom1 = new Adaptor3d_TopolTool(myHS1);
-  Handle(Adaptor3d_TopolTool) dom2 = new Adaptor3d_TopolTool(myHS2);
-  myLConstruct.Load(dom1,dom2,myHS1,myHS2);
+  Handle(Adaptor3d_TopolTool) aDom1 = new Adaptor3d_TopolTool(myHS1);
+  Handle(Adaptor3d_TopolTool) aDom2 = new Adaptor3d_TopolTool(myHS2);
+  myLConstruct.Load(aDom1,aDom2,myHS1,myHS2);
 
   Standard_Real TolArc = Tol;
   Standard_Real TolTang = Tol;
@@ -88,13 +88,13 @@ void GeomInt_IntSS::Perform(const Handle(Geom_Surface)& S1,
   myIntersector.SetTolerances(TolArc,TolTang,UVMaxStep,Deflection);
 
   if(myHS1 == myHS2) {
-    myIntersector.Perform(myHS1,dom1,TolArc,TolTang);
+    myIntersector.Perform(myHS1,aDom1,TolArc,TolTang);
   }
   else if (!useStart) {
-    myIntersector.Perform(myHS1,dom1,myHS2,dom2,TolArc,TolTang);
+    myIntersector.Perform(myHS1,aDom1,myHS2,aDom2,TolArc,TolTang);
   }
   else {
-    myIntersector.Perform(myHS1,dom1,myHS2,dom2,U1,V1,U2,V2,TolArc,TolTang);
+    myIntersector.Perform(myHS1,aDom1,myHS2,aDom2,U1,V1,U2,V2,TolArc,TolTang);
   }
 
   // ============================================================
@@ -102,7 +102,7 @@ void GeomInt_IntSS::Perform(const Handle(Geom_Surface)& S1,
     const Standard_Integer nblin = myIntersector.NbLines();
     for (Standard_Integer i=1; i<= nblin; i++)
     {
-      MakeCurve(i,dom1,dom2,Tol,Approx,ApproxS1,ApproxS2);
+      MakeCurve(i,aDom1,aDom2,Tol,Approx,ApproxS1,ApproxS2);
     }
   }
 }
diff --git a/src/GeomInt/GeomInt_IntSS_1.cxx b/src/GeomInt/GeomInt_IntSS_1.cxx
index 5cac732..0e8c736 100644
--- a/src/GeomInt/GeomInt_IntSS_1.cxx
+++ b/src/GeomInt/GeomInt_IntSS_1.cxx
@@ -257,13 +257,12 @@ static Standard_Boolean isDegenerated(const Handle(GeomAdaptor_HSurface)& theGAH
 //purpose  : 
 //=======================================================================
 void GeomInt_IntSS::MakeCurve(const Standard_Integer Index,
-			                        const Handle(Adaptor3d_TopolTool) & dom1,
-			                        const Handle(Adaptor3d_TopolTool) & dom2,
-			                        const Standard_Real Tol,
-			                        const Standard_Boolean Approx,
-			                        const Standard_Boolean ApproxS1,
-			                        const Standard_Boolean ApproxS2)
-
+                              const Handle(Adaptor3d_TopolTool) & theDom1,
+                              const Handle(Adaptor3d_TopolTool) & theDom2,
+                              const Standard_Real Tol,
+                              const Standard_Boolean Approx,
+                              const Standard_Boolean ApproxS1,
+                              const Standard_Boolean ApproxS2)
 {
   Standard_Boolean myApprox1, myApprox2, myApprox;
   Standard_Real Tolpc, myTolApprox;
@@ -370,7 +369,7 @@ void GeomInt_IntSS::MakeCurve(const Standard_Integer Index,
         }
         Standard_Boolean bFNIt, bLPIt;
         Standard_Real aTestPrm, dT=100.;
-        Standard_Real u1, v1, u2, v2, TolX;
+        Standard_Real u1, v1, u2, v2;
         //
         bFNIt=Precision::IsNegativeInfinite(fprm);
         bLPIt=Precision::IsPositiveInfinite(lprm);
@@ -386,11 +385,10 @@ void GeomInt_IntSS::MakeCurve(const Standard_Integer Index,
         //
         gp_Pnt ptref(newc->Value(aTestPrm));
         //
-        TolX = Precision::Confusion();
         Parameters(myHS1, myHS2, ptref,  u1, v1, u2, v2);
-        ok = (dom1->Classify(gp_Pnt2d(u1, v1), TolX) != TopAbs_OUT);
+        ok = (theDom1->Classify(gp_Pnt2d(u1, v1), Precision::Confusion()) != TopAbs_OUT);
         if(ok) { 
-          ok = (dom2->Classify(gp_Pnt2d(u2,v2),TolX) != TopAbs_OUT); 
+          ok = (theDom2->Classify(gp_Pnt2d(u2, v2), Precision::Confusion()) != TopAbs_OUT);
         }
         if (ok) {
           sline.Append(newc);
@@ -499,18 +497,17 @@ void GeomInt_IntSS::MakeCurve(const Standard_Integer Index,
           }
         }
         //
-        Standard_Real aTwoPIdiv17, u1, v1, u2, v2, TolX;
+        Standard_Real aTwoPIdiv17, u1, v1, u2, v2;
         //
         aTwoPIdiv17=2.*M_PI/17.;
         //
         for (j=0; j<=17; j++) {
           gp_Pnt ptref (newc->Value (j*aTwoPIdiv17));
-          TolX = Precision::Confusion();
 
           Parameters(myHS1, myHS2, ptref, u1, v1, u2, v2);
-          ok = (dom1->Classify(gp_Pnt2d(u1,v1),TolX) != TopAbs_OUT);
+          ok = (theDom1->Classify(gp_Pnt2d(u1, v1), Precision::Confusion()) != TopAbs_OUT);
           if(ok) { 
-            ok = (dom2->Classify(gp_Pnt2d(u2,v2),TolX) != TopAbs_OUT);
+            ok = (theDom2->Classify(gp_Pnt2d(u2, v2), Precision::Confusion()) != TopAbs_OUT);
           }
           if (ok) {
             sline.Append(newc);
diff --git a/src/GeomInt/GeomInt_LineConstructor.cxx b/src/GeomInt/GeomInt_LineConstructor.cxx
index 60948f4..f8dfb76 100644
--- a/src/GeomInt/GeomInt_LineConstructor.cxx
+++ b/src/GeomInt/GeomInt_LineConstructor.cxx
@@ -139,7 +139,7 @@ void GeomInt_LineConstructor::Perform(const Handle(IntPatch_Line)& L)
 {
   Standard_Integer i,nbvtx;
   Standard_Real firstp,lastp;
-  const Standard_Real Tol = Precision::PConfusion() * 35.0;
+  const Standard_Real aTol = Precision::Confusion();
   
   const IntPatch_IType typl = L->ArcType();
   if(typl == IntPatch_Analytic)  {
@@ -155,9 +155,9 @@ void GeomInt_LineConstructor::Perform(const Handle(IntPatch_Line)& L)
         const gp_Pnt Pmid = ALine->Value(pmid);
         Parameters(myHS1,myHS2,Pmid,u1,v1,u2,v2);
         Recadre(myHS1,myHS2,u1,v1,u2,v2);
-        const TopAbs_State in1 = myDom1->Classify(gp_Pnt2d(u1,v1),Tol);
+        const TopAbs_State in1 = myDom1->Classify(gp_Pnt2d(u1,v1),aTol);
         if(in1 !=  TopAbs_OUT) {
-          const TopAbs_State in2 = myDom2->Classify(gp_Pnt2d(u2,v2),Tol);
+          const TopAbs_State in2 = myDom2->Classify(gp_Pnt2d(u2,v2),aTol);
           if(in2 != TopAbs_OUT) { 
             seqp.Append(firstp);
             seqp.Append(lastp);
@@ -182,9 +182,9 @@ void GeomInt_LineConstructor::Perform(const Handle(IntPatch_Line)& L)
           const IntSurf_PntOn2S& Pmid = WLine->Point(pmid);
           Pmid.Parameters(u1,v1,u2,v2);
           Recadre(myHS1,myHS2,u1,v1,u2,v2);
-          const TopAbs_State in1 = myDom1->Classify(gp_Pnt2d(u1,v1),Tol);
+          const TopAbs_State in1 = myDom1->Classify(gp_Pnt2d(u1, v1), aTol);
           if(in1 !=  TopAbs_OUT) {   
-            const TopAbs_State in2 = myDom2->Classify(gp_Pnt2d(u2,v2),Tol);
+            const TopAbs_State in2 = myDom2->Classify(gp_Pnt2d(u2, v2), aTol);
             if(in2 != TopAbs_OUT) {   
               seqp.Append(firstp);
               seqp.Append(lastp);
@@ -195,16 +195,16 @@ void GeomInt_LineConstructor::Perform(const Handle(IntPatch_Line)& L)
           const IntSurf_PntOn2S& Pfirst = WLine->Point((Standard_Integer)(firstp));
           Pfirst.Parameters(u1,v1,u2,v2);
           Recadre(myHS1,myHS2,u1,v1,u2,v2);
-          TopAbs_State in1 = myDom1->Classify(gp_Pnt2d(u1,v1),Tol);
+          TopAbs_State in1 = myDom1->Classify(gp_Pnt2d(u1, v1), aTol);
           if(in1 !=  TopAbs_OUT) {  //-- !=ON donne Pb 
-            TopAbs_State in2 = myDom2->Classify(gp_Pnt2d(u2,v2),Tol);
+            TopAbs_State in2 = myDom2->Classify(gp_Pnt2d(u2, v2), aTol);
             if(in2 != TopAbs_OUT) { //-- !=ON  
               const IntSurf_PntOn2S& Plast = WLine->Point((Standard_Integer)(lastp));
               Plast.Parameters(u1,v1,u2,v2);
               Recadre(myHS1,myHS2,u1,v1,u2,v2);
-              in1 = myDom1->Classify(gp_Pnt2d(u1,v1),Tol);
+              in1 = myDom1->Classify(gp_Pnt2d(u1, v1), aTol);
               if(in1 !=  TopAbs_OUT) {  //-- !=ON donne Pb 
-                in2 = myDom2->Classify(gp_Pnt2d(u2,v2),Tol);
+                in2 = myDom2->Classify(gp_Pnt2d(u2, v2), aTol);
                 if(in2 != TopAbs_OUT) {
                   seqp.Append(firstp);
                   seqp.Append(lastp);
@@ -289,7 +289,7 @@ void GeomInt_LineConstructor::Perform(const Handle(IntPatch_Line)& L)
     Handle(IntPatch_GLine) GLine (Handle(IntPatch_GLine)::DownCast (L));
     //
     if(typl == IntPatch_Circle || typl == IntPatch_Ellipse) { 
-      TreatCircle(L, Tol);
+      TreatCircle(L, aTol);
       done=Standard_True;
       return;
     }
@@ -310,9 +310,9 @@ void GeomInt_LineConstructor::Perform(const Handle(IntPatch_Line)& L)
         //
         Parameters(myHS1,myHS2,Pmid,u1,v1,u2,v2);
         Recadre(myHS1,myHS2,u1,v1,u2,v2);
-        const TopAbs_State in1 = myDom1->Classify(gp_Pnt2d(u1,v1),Tol);
+        const TopAbs_State in1 = myDom1->Classify(gp_Pnt2d(u1, v1), aTol);
         if(in1 !=  TopAbs_OUT) { 
-          const TopAbs_State in2 = myDom2->Classify(gp_Pnt2d(u2,v2),Tol);
+          const TopAbs_State in2 = myDom2->Classify(gp_Pnt2d(u2, v2), aTol);
           if(in2 != TopAbs_OUT) { 
             seqp.Append(firstp);
             seqp.Append(lastp);
@@ -376,7 +376,7 @@ void GeomInt_LineConstructor::Perform(const Handle(IntPatch_Line)& L)
     const Standard_Integer nbinserted = seqpss.Length();
     Standard_Boolean inserted = Standard_False;
     for (Standard_Integer j=1; j<=nbinserted;j++)    {
-      if (Abs(prm-seqpss(j).Parameter()) <= Tol)      {
+      if (Abs(prm-seqpss(j).Parameter()) <= aTol)      {
         // accumulate
         GeomInt_ParameterAndOrientation& valj = seqpss.ChangeValue(j);
         if (or1 != TopAbs_INTERNAL) {
@@ -404,7 +404,7 @@ void GeomInt_LineConstructor::Perform(const Handle(IntPatch_Line)& L)
         break;
       }
       
-      if (prm < seqpss(j).Parameter()-Tol ) {
+      if (prm < seqpss(j).Parameter()-aTol ) {
         // insert before position j
         seqpss.InsertBefore(j,GeomInt_ParameterAndOrientation(prm,or1,or2));
         inserted = Standard_True;
@@ -438,7 +438,7 @@ void GeomInt_LineConstructor::Perform(const Handle(IntPatch_Line)& L)
       if (!GeomInt_LineTool::Vertex(L,i).IsOnDomS1() )      {
         GeomInt_LineTool::Vertex(L,i).ParametersOnS1(U,V);
         gp_Pnt2d PPCC(U,V);
-        if (myDom1->Classify(PPCC,Tol) == TopAbs_OUT) {
+        if (myDom1->Classify(PPCC,aTol) == TopAbs_OUT) {
           done = Standard_True;
           return;
         }
@@ -462,7 +462,7 @@ void GeomInt_LineConstructor::Perform(const Handle(IntPatch_Line)& L)
     for (i=1; i<=GeomInt_LineTool::NbVertex(L); i++ )    {
       if (!GeomInt_LineTool::Vertex(L,i).IsOnDomS2() )      {
         GeomInt_LineTool::Vertex(L,i).ParametersOnS2(U,V);
-        if (myDom2->Classify(gp_Pnt2d(U,V),Tol) == TopAbs_OUT) {
+        if (myDom2->Classify(gp_Pnt2d(U,V),aTol) == TopAbs_OUT) {
           done = Standard_True;
           return;
         }
diff --git a/src/GeomLib/GeomLib.cxx b/src/GeomLib/GeomLib.cxx
index 4d004fa..cb4ca78 100644
--- a/src/GeomLib/GeomLib.cxx
+++ b/src/GeomLib/GeomLib.cxx
@@ -53,20 +53,6 @@
 #include <CSLib.hxx>
 #include <CSLib_NormalStatus.hxx>
 #include <ElCLib.hxx>
-#include <Geom2d_BezierCurve.hxx>
-#include <Geom2d_BSplineCurve.hxx>
-#include <Geom2d_Circle.hxx>
-#include <Geom2d_Curve.hxx>
-#include <Geom2d_Ellipse.hxx>
-#include <Geom2d_Hyperbola.hxx>
-#include <Geom2d_Line.hxx>
-#include <Geom2d_OffsetCurve.hxx>
-#include <Geom2d_Parabola.hxx>
-#include <Geom2d_TrimmedCurve.hxx>
-#include <Geom2dAdaptor_Curve.hxx>
-#include <Geom2dAdaptor_GHCurve.hxx>
-#include <Geom2dAdaptor_HCurve.hxx>
-#include <Geom2dConvert.hxx>
 #include <Geom_BezierCurve.hxx>
 #include <Geom_BezierSurface.hxx>
 #include <Geom_BoundedCurve.hxx>
@@ -84,6 +70,22 @@
 #include <Geom_RectangularTrimmedSurface.hxx>
 #include <Geom_Surface.hxx>
 #include <Geom_TrimmedCurve.hxx>
+#include <Geom2dAdaptor_Curve.hxx>
+#include <Geom2d_BezierCurve.hxx>
+#include <Geom2d_BSplineCurve.hxx>
+#include <Geom2d_Circle.hxx>
+#include <Geom2d_Curve.hxx>
+#include <Geom2d_Ellipse.hxx>
+#include <Geom2d_Hyperbola.hxx>
+#include <Geom2d_Line.hxx>
+#include <Geom2d_OffsetCurve.hxx>
+#include <Geom2d_Parabola.hxx>
+#include <Geom2d_TrimmedCurve.hxx>
+#include <Geom2dAdaptor_Curve.hxx>
+#include <Geom2dAdaptor_GHCurve.hxx>
+#include <Geom2dAdaptor_HCurve.hxx>
+#include <Geom2dConvert.hxx>
+#include <Geom2dLProp_CLProps2d.hxx>
 #include <GeomAdaptor_HSurface.hxx>
 #include <GeomAdaptor_Surface.hxx>
 #include <GeomConvert.hxx>
@@ -135,6 +137,7 @@
 #include <TColStd_Array2OfReal.hxx>
 #include <TColStd_HArray1OfReal.hxx>
 #include <TColStd_HArray2OfReal.hxx>
+
 //
 static Standard_Boolean CompareWeightPoles(const TColgp_Array1OfPnt& thePoles1, 
                                            const TColStd_Array1OfReal* const theW1,
@@ -2752,6 +2755,31 @@ Standard_Boolean GeomLib::IsBzVClosed (const Handle(Geom_BezierSurface)& S,
 }
 
 //=======================================================================
+//function : LocalGeometry
+//purpose  : 
+//=======================================================================
+Standard_Boolean GeomLib::LocalGeometry(const Handle(Geom2d_Curve)& theC,
+                                        const Standard_Real theParam,
+                                        gp_Dir2d& theTan,
+                                        gp_Dir2d& theNormal,
+                                        Standard_Real& theCurvature)
+{
+  Geom2dLProp_CLProps2d aProp(theC, theParam, 2, Precision::PConfusion());
+
+  if(!aProp.IsTangentDefined())
+    return Standard_False;
+
+  aProp.Tangent(theTan);
+  theCurvature = aProp.Curvature();
+  if((theCurvature > Precision::PConfusion()) && (theCurvature < RealLast()))
+    aProp.Normal(theNormal);
+  else
+    theNormal.SetCoord(theTan.Y(), -theTan.X());
+
+  return Standard_True;
+}
+
+//=======================================================================
 //function : CompareWeightPoles
 //purpose  : Checks if thePoles1(i)*theW1(i) is equal to thePoles2(i)*theW2(i)
 //            with tolerance theTol.
diff --git a/src/GeomLib/GeomLib.hxx b/src/GeomLib/GeomLib.hxx
index b51028d..cfaa956 100644
--- a/src/GeomLib/GeomLib.hxx
+++ b/src/GeomLib/GeomLib.hxx
@@ -223,6 +223,16 @@ public:
                                                         const Standard_Real V2,
                                                         const Standard_Real Tol);
 
+  //! Writes in <theTan>,  <theNormal> and <theCurvature>  the tangent,  normal
+  //! and  curvature of the curve <theC> at parameter value <theParam>.
+  //! Returns FALSE if properties cannot be computed.
+  Standard_EXPORT static
+    Standard_Boolean LocalGeometry(const Handle(Geom2d_Curve)& theC,
+                                      const Standard_Real theParam,
+                                      gp_Dir2d& theTan,
+                                      gp_Dir2d& theNormal,
+                                      Standard_Real& theCurvature);
+  
 protected:
 
 
diff --git a/src/GeometryTest/GeometryTest_CurveCommands.cxx b/src/GeometryTest/GeometryTest_CurveCommands.cxx
index 5e6ad44..2be5ad7 100644
--- a/src/GeometryTest/GeometryTest_CurveCommands.cxx
+++ b/src/GeometryTest/GeometryTest_CurveCommands.cxx
@@ -1772,6 +1772,44 @@ static Standard_Integer GetCurveContinuity( Draw_Interpretor& theDI,
 }
 
 //=======================================================================
+//function : GetResolution
+//purpose  : Returns the resolution of the given curve
+//=======================================================================
+static Standard_Integer GetResolution(Draw_Interpretor& theDI,
+                                      Standard_Integer theNArg,
+                                      const char** theArgv)
+{
+  if (theNArg != 3)
+  {
+    theDI << "Use: curvresolution <3d/2d-curve> toler \n";
+    return 1;
+  }
+
+  const Standard_Real aTol = Draw::Atof(theArgv[2]);  
+
+  Handle(Geom2d_Curve) aGC2d = DrawTrSurf::GetCurve2d(theArgv[1]);
+  Handle(Geom_Curve) aGC3d = DrawTrSurf::GetCurve(theArgv[1]);
+  if (aGC3d.IsNull() && aGC2d.IsNull())
+  {
+    theDI << theArgv[1] << " is not a 2D/3D-curve!\n";
+    return 1;
+  }
+
+  if (!aGC3d.IsNull())
+  {
+    Handle(Adaptor3d_HCurve) anAd = new GeomAdaptor_HCurve(aGC3d);
+    theDI << "Res3dCurve = " << anAd->Resolution(aTol) << "\n";
+  }
+  else //if (!aGC2d.IsNull())
+  {
+    Handle(Adaptor2d_HCurve2d) anAd = new Geom2dAdaptor_HCurve(aGC2d);
+    theDI << "Res2dCurve = " << anAd->Resolution(aTol) << "\n";
+  }
+
+  return 0;
+}
+
+//=======================================================================
 //function : CurveCommands
 //purpose  : 
 //=======================================================================
@@ -1878,6 +1916,10 @@ void  GeometryTest::CurveCommands(Draw_Interpretor& theCommands)
 		  __FILE__,
 		  GetCurveContinuity,g);
 
+  theCommands.Add("curvresolution",
+                  "curvresolution <3d/2d-curve> toler: \n\tReturns the resolution of the given curve",
+                  __FILE__,
+                  GetResolution, g);
 
 }
 
diff --git a/src/GeometryTest/GeometryTest_SurfaceCommands.cxx b/src/GeometryTest/GeometryTest_SurfaceCommands.cxx
index 5b5636f..f41b4a6 100644
--- a/src/GeometryTest/GeometryTest_SurfaceCommands.cxx
+++ b/src/GeometryTest/GeometryTest_SurfaceCommands.cxx
@@ -36,6 +36,7 @@
 
 
 #include <GeomAdaptor_Surface.hxx>
+#include <GeomAdaptor_HSurface.hxx>
 #include <GeomAdaptor_Curve.hxx>
 #include <Geom2dAdaptor_Curve.hxx>
 
@@ -371,6 +372,36 @@ static Standard_Integer GetSurfaceContinuity( Draw_Interpretor& theDI,
   return 0;
 }
 
+//=======================================================================
+//function : GetResolution
+//purpose  : Returns the resolution of the given surface
+//=======================================================================
+static Standard_Integer GetResolution(Draw_Interpretor& theDI,
+                                      Standard_Integer theNArg,
+                                      const char** theArgv)
+{
+  if (theNArg != 3)
+  {
+    theDI << "Use: surfresolution surface toler \n";
+    return 1;
+  }
+
+  const Standard_Real aTol = Draw::Atof(theArgv[2]);
+
+  Handle(Geom_Surface) aGS = DrawTrSurf::GetSurface(theArgv[1]);
+  if (aGS.IsNull())
+  {
+    theDI << "Argument is not a surface!\n";
+    return 1;
+  }
+
+  Handle(Adaptor3d_HSurface) anAS = new GeomAdaptor_HSurface(aGS);
+  theDI << "Ures = " << anAS->UResolution(aTol) <<
+           "; Vres = " << anAS->VResolution(aTol) << "\n";
+
+  return 0;
+}
+
 
 //=======================================================================
 //function : SurfaceCommands
@@ -425,7 +456,10 @@ void  GeometryTest::SurfaceCommands(Draw_Interpretor& theCommands)
 		  __FILE__,
 		  GetSurfaceContinuity,g);
 
-
+ theCommands.Add("surfresolution",
+                 "surfresolution surface toler: \n\tReturns the resolution of the given surface",
+                 __FILE__,
+                 GetResolution, g);
 }
 
 
diff --git a/src/GeomliteTest/GeomliteTest_CurveCommands.cxx b/src/GeomliteTest/GeomliteTest_CurveCommands.cxx
index 180bae2..7308ba6 100644
--- a/src/GeomliteTest/GeomliteTest_CurveCommands.cxx
+++ b/src/GeomliteTest/GeomliteTest_CurveCommands.cxx
@@ -1842,7 +1842,46 @@ static Standard_Integer length(Draw_Interpretor& di,
   return 0;
 }
 
+//=======================================================================
+//function : Polyline2D
+//purpose  : Builds 2D-polygon from set of points. These points will 
+//            be joined by linear segments.
+//=======================================================================
+static Standard_Integer Polyline2D(Draw_Interpretor& theDI,
+                                   Standard_Integer theNArg,
+                                   const char** theArgVal)
+{
+  if (theNArg < 6)
+  {
+    //                0         1     2   3   4   5
+    theDI << "Use: 2dpolyline result px1 py1 px2 py2 ...";
+    return 1;
+  }
+
+  const Standard_Integer aDegree = 1;
+  const Standard_Integer aNbPoles = (theNArg - 2) / 2;
+  TColStd_Array1OfReal anArrOfKnots(1, aNbPoles);
+  TColStd_Array1OfInteger anArrOfMults(1, aNbPoles);
+  TColgp_Array1OfPnt2d anArrOfPoles(1, aNbPoles);
 
+  const Standard_Integer anArgMax = theNArg - 1;
+  for (Standard_Integer aCurrArg = 1, aPID = 1; aCurrArg < anArgMax; aPID++)
+  {
+    anArrOfKnots(aPID) = aPID;
+    anArrOfMults(aPID) = aDegree;
+    const Standard_Real aX = Draw::Atof(theArgVal[++aCurrArg]);
+    const Standard_Real aY = Draw::Atof(theArgVal[++aCurrArg]);
+    anArrOfPoles(aPID).SetCoord(aX, aY);
+  }
+
+  anArrOfMults(anArrOfMults.Lower())++;
+  anArrOfMults(anArrOfMults.Upper())++;
+
+  const Handle(Geom2d_BSplineCurve) aCurv = new Geom2d_BSplineCurve(anArrOfPoles, anArrOfKnots, anArrOfMults, aDegree);
+  DrawTrSurf::Set(theArgVal[1], aCurv);
+
+  return 0;
+}
 
 //=======================================================================
 //function : CurveCommands
@@ -2079,6 +2118,7 @@ void  GeomliteTest::CurveCommands(Draw_Interpretor& theCommands)
 		  __FILE__,
 		  canceldenom,g);
 
- 
+  theCommands.Add("2dpolyline", "2dpolyline result px1 py1 px2 py2 ...",
+                  __FILE__, Polyline2D, g);
 
 }
diff --git a/src/HLRBRep/HLRBRep_Data.cxx b/src/HLRBRep/HLRBRep_Data.cxx
index 72e8f07..71d86cd 100644
--- a/src/HLRBRep/HLRBRep_Data.cxx
+++ b/src/HLRBRep/HLRBRep_Data.cxx
@@ -1941,7 +1941,7 @@ HLRBRep_Data::Classify (const Standard_Integer E,
             GeomInt::AdjustPeriodic(v, VMin, VMax, PeriodV, v, aDummyShift);
 	  
           gp_Pnt2d pnt2d(u, v);
-          if (myClassifier->Classify(pnt2d, Precision::PConfusion())
+          if (myClassifier->Classify(pnt2d, Precision::Confusion())
             != TopAbs_OUT)
           {
             state = TopAbs_IN;
diff --git a/src/IntCurvesFace/IntCurvesFace_Intersector.cxx b/src/IntCurvesFace/IntCurvesFace_Intersector.cxx
index 2893608..9e9fa68 100644
--- a/src/IntCurvesFace/IntCurvesFace_Intersector.cxx
+++ b/src/IntCurvesFace/IntCurvesFace_Intersector.cxx
@@ -228,7 +228,6 @@ void IntCurvesFace_Intersector::InternalCall(const IntCurveSurface_HInter &HICS,
     //Calculate tolerance for 2d classifier
     Standard_Real mintol3d = BRep_Tool::Tolerance(face);
     Standard_Real maxtol3d = mintol3d;
-    Standard_Real mintol2d = Tol, maxtol2d = Tol;
     TopExp_Explorer anExp(face, TopAbs_EDGE);
     for(; anExp.More(); anExp.Next())
     {
@@ -236,24 +235,20 @@ void IntCurvesFace_Intersector::InternalCall(const IntCurveSurface_HInter &HICS,
       mintol3d = Min(mintol3d, curtol);
       maxtol3d = Max(maxtol3d, curtol);
     }
-    Standard_Real minres = Max(Hsurface->UResolution(mintol3d), Hsurface->VResolution(mintol3d));
-    Standard_Real maxres = Max(Hsurface->UResolution(maxtol3d), Hsurface->VResolution(maxtol3d));
-    mintol2d = Max(minres, Tol); 
-    maxtol2d = Max(maxres, Tol);
-    //
+
     Handle(BRepTopAdaptor_TopolTool) anAdditionalTool;
     for(Standard_Integer index=HICS.NbPoints(); index>=1; index--) {  
       const IntCurveSurface_IntersectionPoint& HICSPointindex = HICS.Point(index);
       gp_Pnt2d Puv(HICSPointindex.U(),HICSPointindex.V());
 
       //TopAbs_State currentstate = myTopolTool->Classify(Puv,Tol);
-      TopAbs_State currentstate = myTopolTool->Classify(Puv, !myUseBoundTol ? 0 : mintol2d);
-      if(myUseBoundTol && currentstate == TopAbs_OUT && maxtol2d > mintol2d) {
+      TopAbs_State currentstate = myTopolTool->Classify(Puv, !myUseBoundTol ? 0 : mintol3d);
+      if(myUseBoundTol && currentstate == TopAbs_OUT) {
         if(anAdditionalTool.IsNull())
         {
           anAdditionalTool = new BRepTopAdaptor_TopolTool(Hsurface);
         }
-        currentstate = anAdditionalTool->Classify(Puv,maxtol2d);
+        currentstate = anAdditionalTool->Classify(Puv, maxtol3d);
         if(currentstate == TopAbs_ON)
         {
           currentstate = TopAbs_OUT;
@@ -489,7 +484,7 @@ Bnd_Box IntCurvesFace_Intersector::Bounding() const {
   }
 }
 TopAbs_State IntCurvesFace_Intersector::ClassifyUVPoint(const gp_Pnt2d& Puv) const { 
-  TopAbs_State state = myTopolTool->Classify(Puv,1e-7);
+  TopAbs_State state = myTopolTool->Classify(Puv,Precision::Confusion());
   return(state);
 }
 //============================================================================
diff --git a/src/IntPatch/IntPatch_ImpPrmIntersection.cxx b/src/IntPatch/IntPatch_ImpPrmIntersection.cxx
index 5c74b94..33ea1a7 100644
--- a/src/IntPatch/IntPatch_ImpPrmIntersection.cxx
+++ b/src/IntPatch/IntPatch_ImpPrmIntersection.cxx
@@ -629,29 +629,21 @@ void IntPatch_ImpPrmIntersection::Perform (const Handle(Adaptor3d_HSurface)& Sur
     //plane only touches surface and does not cross it,
     //so no inner points exist.
     SearchIns = Standard_False;
-    Handle(Adaptor3d_TopolTool) T;
-    if(reversed)
-    {
-      T = D1;
-    }
-    else
-    {
-      T = D2;
-    }
+    const Handle(Adaptor3d_TopolTool) anADTT = (reversed) ? D1 : D2;
     Standard_Integer aNbSamples = 0;
-    aNbSamples = T->NbSamples();
+    aNbSamples = anADTT->NbSamples();
     gp_Pnt2d s2d;
     gp_Pnt s3d;
     Standard_Real aValf[1], aUVap[2];
     math_Vector Valf(aValf,1,1), UVap(aUVap,1,2);
-    T->SamplePoint(1,s2d, s3d);
+    anADTT->SamplePoint(1, s2d, s3d);
     UVap(1)=s2d.X(); 
     UVap(2)=s2d.Y();
     Func.Value(UVap,Valf);
     Standard_Real rvalf = Sign(1.,Valf(1));
     for(Standard_Integer i = 2; i <= aNbSamples; ++i)
     {
-      T->SamplePoint(i,s2d, s3d);
+      anADTT->SamplePoint(i, s2d, s3d);
       UVap(1)=s2d.X(); 
       UVap(2)=s2d.Y();
       Func.Value(UVap,Valf);
diff --git a/src/IntPatch/IntPatch_Intersection.hxx b/src/IntPatch/IntPatch_Intersection.hxx
index 5c5780e..6fb708a 100644
--- a/src/IntPatch/IntPatch_Intersection.hxx
+++ b/src/IntPatch/IntPatch_Intersection.hxx
@@ -150,13 +150,6 @@ public:
 
 protected:
 
-
-
-
-
-private:
-
-  
   Standard_EXPORT void ParamParamPerfom (const Handle(Adaptor3d_HSurface)& S1, const Handle(Adaptor3d_TopolTool)& D1, const Handle(Adaptor3d_HSurface)& S2, const Handle(Adaptor3d_TopolTool)& D2, const Standard_Real TolArc, const Standard_Real TolTang, IntSurf_ListOfPntOn2S& LOfPnts, const GeomAbs_SurfaceType typs1, const GeomAbs_SurfaceType typs2);
   
   //! Flag theIsReqToKeepRLine has been entered only for
@@ -170,6 +163,8 @@ private:
   Standard_EXPORT void GeomParamPerfom (const Handle(Adaptor3d_HSurface)& S1, const Handle(Adaptor3d_TopolTool)& D1, const Handle(Adaptor3d_HSurface)& S2, const Handle(Adaptor3d_TopolTool)& D2, const Standard_Boolean isNotAnalitical, const GeomAbs_SurfaceType typs1, const GeomAbs_SurfaceType typs2);
 
 
+private:
+  
   Standard_Boolean done;
   Standard_Boolean empt;
   Standard_Boolean tgte;
diff --git a/src/IntStart/IntStart_SearchInside.gxx b/src/IntStart/IntStart_SearchInside.gxx
index 53a2225..c9e1cb1 100644
--- a/src/IntStart/IntStart_SearchInside.gxx
+++ b/src/IntStart/IntStart_SearchInside.gxx
@@ -72,15 +72,6 @@ void IntStart_SearchInside::Perform (TheFunction& Func,
   
   Standard_Real toler1 = toler(1) = ThePSurfaceTool::UResolution(PS,Precision::Confusion());
   Standard_Real toler2 = toler(2) = ThePSurfaceTool::VResolution(PS,Precision::Confusion());
-  Standard_Real Maxtoler1toler2 = toler1;
-  if(toler2>Maxtoler1toler2) Maxtoler1toler2 = toler2;
-
-  //-- lbr le 15 mai 97
-  //-- on interdit aux points d'etre trop prets des restrictions 
-  Maxtoler1toler2*=1000;
-  if(Maxtoler1toler2>du*0.001) Maxtoler1toler2=du*0.001;
-  if(Maxtoler1toler2>dv*0.001) Maxtoler1toler2=dv*0.001;
-  
   
   Func.Set(PS);
   Standard_Real Tol = Func.Tolerance();
@@ -199,15 +190,17 @@ void IntStart_SearchInside::Perform (TheFunction& Func,
 		testpnt = (j <= nbpt);
 	      }
 	    }
-	    if (j > nbpt) {
-	      //	    situ = TheSITool::Classify(PS,UVap(1),UVap(2));
-	      situ = T->Classify(gp_Pnt2d(UVap(1),UVap(2)),
-				 Maxtoler1toler2,Standard_False);   //-- ,Standard_False pour ne pas recadrer on Periodic
-	      if (situ == TopAbs_IN) {
-		list.Append(IntSurf_InteriorPoint(psol,UVap(1),UVap(2),
-						  Func.Direction3d(),
-						  Func.Direction2d()));
-	      }
+            if (j > nbpt)
+            {
+              //Standard_False pour ne pas recadrer on Periodic
+              situ = T->Classify(gp_Pnt2d(UVap(1), UVap(2)),
+                                    Precision::Confusion(), Standard_False);
+              if (situ == TopAbs_IN)
+              {
+                list.Append(IntSurf_InteriorPoint(psol, UVap(1), UVap(2),
+                                                  Func.Direction3d(),
+                                                  Func.Direction2d()));
+              }
 	    }
 	  }
 	}
diff --git a/src/IntTools/FILES b/src/IntTools/FILES
index 6917e7b..59d8222 100644
--- a/src/IntTools/FILES
+++ b/src/IntTools/FILES
@@ -38,8 +38,6 @@ IntTools_EdgeFace.cxx
 IntTools_EdgeFace.hxx
 IntTools_FaceFace.cxx
 IntTools_FaceFace.hxx
-IntTools_FClass2d.cxx
-IntTools_FClass2d.hxx
 IntTools_ListIteratorOfListOfBox.hxx
 IntTools_ListIteratorOfListOfCurveRangeSample.hxx
 IntTools_ListIteratorOfListOfSurfaceRangeSample.hxx
@@ -80,5 +78,5 @@ IntTools_Tools.cxx
 IntTools_Tools.hxx
 IntTools_TopolTool.cxx
 IntTools_TopolTool.hxx
+IntTools_WLineTool.cxx
 IntTools_WLineTool.hxx
-IntTools_WLineTool.cxx
\ No newline at end of file
diff --git a/src/IntTools/IntTools.hxx b/src/IntTools/IntTools.hxx
index 853c126..a052cb3 100644
--- a/src/IntTools/IntTools.hxx
+++ b/src/IntTools/IntTools.hxx
@@ -35,7 +35,6 @@ class IntTools_CommonPrt;
 class IntTools_Root;
 class IntTools_EdgeEdge;
 class IntTools_EdgeFace;
-class IntTools_FClass2d;
 class IntTools_MarkedRangeSet;
 class IntTools_BaseRangeSample;
 class IntTools_CurveRangeSample;
@@ -107,7 +106,6 @@ friend class IntTools_CommonPrt;
 friend class IntTools_Root;
 friend class IntTools_EdgeEdge;
 friend class IntTools_EdgeFace;
-friend class IntTools_FClass2d;
 friend class IntTools_MarkedRangeSet;
 friend class IntTools_BaseRangeSample;
 friend class IntTools_CurveRangeSample;
diff --git a/src/IntTools/IntTools_Context.cxx b/src/IntTools/IntTools_Context.cxx
index 010425c..64ad3b1 100644
--- a/src/IntTools/IntTools_Context.cxx
+++ b/src/IntTools/IntTools_Context.cxx
@@ -19,6 +19,7 @@
 #include <BRepAdaptor_Surface.hxx>
 #include <BRepBndLib.hxx>
 #include <BRepClass3d_SolidClassifier.hxx>
+#include <BRepTopAdaptor_FClass2d.hxx>
 #include <Extrema_LocateExtPC.hxx>
 #include <Geom2d_Curve.hxx>
 #include <Geom2d_TrimmedCurve.hxx>
@@ -33,7 +34,6 @@
 #include <gp_Pnt2d.hxx>
 #include <IntTools_Context.hxx>
 #include <IntTools_Curve.hxx>
-#include <IntTools_FClass2d.hxx>
 #include <IntTools_SurfaceRangeLocalizeData.hxx>
 #include <IntTools_Tools.hxx>
 #include <Precision.hxx>
@@ -103,13 +103,13 @@ IntTools_Context::~IntTools_Context()
   DataMapOfShapeAddress::Iterator aIt;
   DataMapOfTransientAddress::Iterator aIt1;
   //
-  IntTools_FClass2d* pFClass2d;
+  BRepTopAdaptor_FClass2d* pFClass2d;
   //
   aIt.Initialize(myFClass2dMap);
   for (; aIt.More(); aIt.Next()) {
     anAdr=aIt.Value();
-    pFClass2d=(IntTools_FClass2d*)anAdr;
-    (*pFClass2d).~IntTools_FClass2d();
+    pFClass2d = (BRepTopAdaptor_FClass2d*)anAdr;
+    (*pFClass2d).~BRepTopAdaptor_FClass2d();
     myAllocator->Free(anAdr); 
   }
   myFClass2dMap.Clear();
@@ -254,28 +254,23 @@ Standard_Boolean IntTools_Context::IsInfiniteFace
 //function : FClass2d
 //purpose  : 
 //=======================================================================
-IntTools_FClass2d& IntTools_Context::FClass2d(const TopoDS_Face& aF)
+BRepTopAdaptor_FClass2d& IntTools_Context::FClass2d(const TopoDS_Face& aF)
 {
-  Standard_Address anAdr;
-  IntTools_FClass2d* pFClass2d;
+  BRepTopAdaptor_FClass2d* pFClass2d;
   //
   if (!myFClass2dMap.IsBound(aF)) {
-    Standard_Real aTolF;
-    TopoDS_Face aFF;
-    //
-    aFF=aF;
-    aFF.Orientation(TopAbs_FORWARD);
-    aTolF=BRep_Tool::Tolerance(aFF);
-    //
-    pFClass2d=(IntTools_FClass2d*)myAllocator->Allocate(sizeof(IntTools_FClass2d));
-    new (pFClass2d) IntTools_FClass2d(aFF, aTolF);
+    const TopoDS_Face aFF = TopoDS::Face(aF.Oriented(TopAbs_FORWARD));
+    const Standard_Real aTolF=BRep_Tool::Tolerance(aFF);
     //
-    anAdr=(Standard_Address)pFClass2d;
-    myFClass2dMap.Bind(aFF, anAdr);
+    pFClass2d = (BRepTopAdaptor_FClass2d*)myAllocator->
+                        Allocate(sizeof(BRepTopAdaptor_FClass2d));
+    new (pFClass2d)BRepTopAdaptor_FClass2d(aFF, aTolF);
+
+    myFClass2dMap.Bind(aFF, (Standard_Address)pFClass2d);
   }
-  else {
-    anAdr=myFClass2dMap.Find(aF);
-    pFClass2d=(IntTools_FClass2d*)anAdr;
+  else
+  {
+    pFClass2d = (BRepTopAdaptor_FClass2d*)(myFClass2dMap.Find(aF));
   }
   return *pFClass2d;
 }
@@ -703,12 +698,11 @@ Standard_Integer IntTools_Context::ComputeVF
 //function : StatePointFace
 //purpose  : 
 //=======================================================================
-TopAbs_State IntTools_Context::StatePointFace
-  (const TopoDS_Face& aF,
-   const gp_Pnt2d& aP2d)
+TopAbs_State IntTools_Context::StatePointFace(const TopoDS_Face& aF,
+                                              const gp_Pnt2d& aP2d)
 {
   TopAbs_State aState;
-  IntTools_FClass2d& aClass2d=FClass2d(aF);
+  BRepTopAdaptor_FClass2d& aClass2d = FClass2d(aF);
   aState=aClass2d.Perform(aP2d);
   return aState;
 }
diff --git a/src/IntTools/IntTools_Context.hxx b/src/IntTools/IntTools_Context.hxx
index 3ec1dcf..9f9e7ad 100644
--- a/src/IntTools/IntTools_Context.hxx
+++ b/src/IntTools/IntTools_Context.hxx
@@ -29,7 +29,6 @@
 #include <Standard_Boolean.hxx>
 #include <BRepAdaptor_Surface.hxx>
 #include <TColStd_MapTransientHasher.hxx>
-class IntTools_FClass2d;
 class TopoDS_Face;
 class GeomAPI_ProjectPointOnSurf;
 class GeomAPI_ProjectPointOnCurve;
@@ -37,6 +36,7 @@ class TopoDS_Edge;
 class Geom_Curve;
 class IntTools_SurfaceRangeLocalizeData;
 class BRepClass3d_SolidClassifier;
+class BRepTopAdaptor_FClass2d;
 class TopoDS_Solid;
 class Geom2dHatch_Hatcher;
 class gp_Pnt;
@@ -64,7 +64,7 @@ Standard_EXPORT virtual  ~IntTools_Context();
 
   //! Returns a reference to point classifier
   //! for given face
-  Standard_EXPORT IntTools_FClass2d& FClass2d (const TopoDS_Face& aF);
+  Standard_EXPORT BRepTopAdaptor_FClass2d& FClass2d(const TopoDS_Face& aF);
   
 
   //! Returns a reference to point projector
diff --git a/src/IntTools/IntTools_EdgeEdge.cxx b/src/IntTools/IntTools_EdgeEdge.cxx
index 38c3646..04cffb3 100644
--- a/src/IntTools/IntTools_EdgeEdge.cxx
+++ b/src/IntTools/IntTools_EdgeEdge.cxx
@@ -888,20 +888,6 @@ void IntTools_EdgeEdge::ComputeLineLine()
     return;
   }
   //
-  {
-    TopoDS_Iterator aIt1, aIt2;
-    aIt1.Initialize(myEdge1);
-    for (; aIt1.More(); aIt1.Next()) {
-      const TopoDS_Shape& aV1 = aIt1.Value();
-      aIt2.Initialize(myEdge2);
-      for (; aIt2.More(); aIt2.Next()) {
-        const TopoDS_Shape& aV2 = aIt2.Value();
-        if (aV2.IsSame(aV1)) {
-          return;
-        }
-      }
-    }
-  }
   //
   aSin = 1. - aCos*aCos;
   gp_Pnt O1 = aL1.Location();
diff --git a/src/IntTools/IntTools_EdgeFace.cxx b/src/IntTools/IntTools_EdgeFace.cxx
index 36f181e..02a002f 100644
--- a/src/IntTools/IntTools_EdgeFace.cxx
+++ b/src/IntTools/IntTools_EdgeFace.cxx
@@ -18,6 +18,7 @@
 #include <BndLib_AddSurface.hxx>
 #include <BRep_Tool.hxx>
 #include <BRepAdaptor_Surface.hxx>
+#include <BRepTopAdaptor_FClass2d.hxx>
 #include <Extrema_ExtCS.hxx>
 #include <Extrema_POnCurv.hxx>
 #include <Extrema_POnSurf.hxx>
@@ -44,7 +45,6 @@
 #include <IntTools_CommonPrt.hxx>
 #include <IntTools_Context.hxx>
 #include <IntTools_EdgeFace.hxx>
-#include <IntTools_FClass2d.hxx>
 #include <IntTools_Range.hxx>
 #include <IntTools_Root.hxx>
 #include <IntTools_Tools.hxx>
@@ -124,11 +124,11 @@ Standard_Boolean IntTools_EdgeFace::IsCoincident()
     //We classify only three points: in the begin, in the 
     //end and in the middle of the edge.
     //However, exact middle point (when i == (aNbSeg + 1)/2)
-    //can be unprojectable. Therefore, it will not be able to
+    //can be nonprojectable. Therefore, it will not be able to
     //be classified. Therefore, points with indexes in 
     //[aTreshIdxF, aTreshIdxL] range are made available 
     //for classification.
-    //isClassified == TRUE if MIDDLE point has been choosen and
+    //isClassified == TRUE if MIDDLE point has been chosen and
     //classified correctly.
 
     if(((0 < i) && (i < aTreshIdxF)) || ((aTreshIdxL < i ) && (i < aNbSeg)))
@@ -141,7 +141,7 @@ Standard_Boolean IntTools_EdgeFace::IsCoincident()
     aP2d.SetX(aU);
     aP2d.SetY(aV);
 
-    IntTools_FClass2d& aClass2d=myContext->FClass2d(myFace);
+    BRepTopAdaptor_FClass2d& aClass2d = myContext->FClass2d(myFace);
     aState = aClass2d.Perform(aP2d);
     
     if(aState == TopAbs_OUT)
diff --git a/src/IntTools/IntTools_FClass2d.cxx b/src/IntTools/IntTools_FClass2d.cxx
deleted file mode 100644
index 13863dd..0000000
--- a/src/IntTools/IntTools_FClass2d.cxx
+++ /dev/null
@@ -1,919 +0,0 @@
-// Created on: 1995-03-22
-// Created by: Laurent BUCHARD
-// Copyright (c) 1995-1999 Matra Datavision
-// Copyright (c) 1999-2014 OPEN CASCADE SAS
-//
-// This file is part of Open CASCADE Technology software library.
-//
-// This library is free software; you can redistribute it and/or modify it under
-// the terms of the GNU Lesser General Public License version 2.1 as published
-// by the Free Software Foundation, with special exception defined in the file
-// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
-// distribution for complete text of the license and disclaimer of any warranty.
-//
-// Alternatively, this file may be used under the terms of Open CASCADE
-// commercial license or contractual agreement.
-
-
-#include <BRep_Tool.hxx>
-#include <BRepAdaptor_Curve.hxx>
-#include <BRepAdaptor_Curve2d.hxx>
-#include <BRepAdaptor_HSurface.hxx>
-#include <BRepClass_FaceClassifier.hxx>
-#include <BRepTools_WireExplorer.hxx>
-#include <CSLib_Class2d.hxx>
-#include <ElCLib.hxx>
-#include <Geom2dInt_Geom2dCurveTool.hxx>
-#include <GeomAbs_SurfaceType.hxx>
-#include <GeomInt.hxx>
-#include <GCPnts_QuasiUniformDeflection.hxx>
-#include <gp_Pnt.hxx>
-#include <gp_Pnt2d.hxx>
-#include <IntTools_FClass2d.hxx>
-#include <IntTools_Tools.hxx>
-#include <Precision.hxx>
-#include <TColgp_Array1OfPnt2d.hxx>
-#include <TColgp_SequenceOfPnt2d.hxx>
-#include <TColgp_SequenceOfVec2d.hxx>
-#include <TColStd_DataMapOfIntegerInteger.hxx>
-#include <TopAbs_Orientation.hxx>
-#include <TopExp.hxx>
-#include <TopExp_Explorer.hxx>
-#include <TopoDS.hxx>
-#include <TopoDS_Edge.hxx>
-#include <TopoDS_Face.hxx>
-#include <TopoDS_Wire.hxx>
-
-#include <stdio.h>
-
-//#define DEBUG_PCLASS_POLYGON
-#ifdef DEBUG_PCLASS_POLYGON
-#include <DrawTrSurf.hxx>
-#include <Geom2d_BSplineCurve.hxx>
-#endif
-
-//=======================================================================
-//function : IntTools_FClass2d:IntTools:_FClass2d
-//purpose  : 
-//=======================================================================
-IntTools_FClass2d::IntTools_FClass2d()
-{
-}
-//=======================================================================
-//function : IntTools_FClass2d::IntTools_FClass2d
-//purpose  : 
-//=======================================================================
-IntTools_FClass2d::IntTools_FClass2d(const TopoDS_Face& aFace,
-				     const Standard_Real TolUV) 
-: Toluv(TolUV), Face(aFace)  
-{
-  Init(Face, Toluv);
-}
-//=======================================================================
-//function : IsHole
-//purpose  : 
-//=======================================================================
-Standard_Boolean IntTools_FClass2d::IsHole() const
-{
-  return myIsHole;
-} 
-//=======================================================================
-//function : Init
-//purpose  : 
-//=======================================================================
-void IntTools_FClass2d::Init(const TopoDS_Face& aFace,
-			     const Standard_Real TolUV) 
-{
-  Standard_Boolean WireIsNotEmpty, Ancienpnt3dinitialise, degenerated;
-  Standard_Integer nbpnts, firstpoint, NbEdges;
-  Standard_Integer iX, aNbs1, nbs, Avant, BadWire;
-  Standard_Real u, du, Tole, Tol, pfbid, plbid;
-  Standard_Real FlecheU, FlecheV, TolVertex1, TolVertex;
-  Standard_Real uFirst, uLast;
-  Standard_Real aPrCf, aPrCf2;
-  //
-  TopoDS_Edge  edge;
-  TopoDS_Vertex Va,Vb;
-  TopAbs_Orientation Or;
-  BRepTools_WireExplorer aWExp;
-  TopExp_Explorer aExpF, aExp;
-  Handle(Geom2d_Curve) aC2D;
-  gp_Pnt Ancienpnt3d;
-  TColgp_SequenceOfPnt2d SeqPnt2d;
-  TColStd_DataMapOfIntegerInteger anIndexMap;
-  TColgp_SequenceOfVec2d          aD1Prev;
-  TColgp_SequenceOfVec2d          aD1Next;
-  //
-  aPrCf=Precision::Confusion();
-  aPrCf2=aPrCf*aPrCf;
-  myIsHole=Standard_True;
-  //
-  Toluv=TolUV;
-  Face=aFace;
-  Face.Orientation(TopAbs_FORWARD);
-  Handle(BRepAdaptor_HSurface) surf = new BRepAdaptor_HSurface();
-  surf->ChangeSurface().Initialize(aFace, Standard_False);
-  //
-  Tole = 0.;
-  Tol=0.;
-  Umin = Vmin = RealLast();
-  Umax = Vmax = -Umin;
-  BadWire=0;
-  //
-  //if face has several wires and one of them is bad,
-  //it is necessary to process all of them for correct
-  //calculation of Umin, Umax, Vmin, Vmax - ifv, 23.08.06 
-  //
-  aExpF.Init(Face,TopAbs_WIRE); 
-  for(; aExpF.More();  aExpF.Next()) {
-    const TopoDS_Wire& aW=*((TopoDS_Wire*)&aExpF.Current());
-    //
-    nbpnts = 0;
-    firstpoint =1;
-    FlecheU = 0.;
-    FlecheV = 0.;
-    TolVertex1=0.;
-    TolVertex=0.;
-    WireIsNotEmpty = Standard_False;
-    Ancienpnt3dinitialise=Standard_False;
-    Ancienpnt3d.SetCoord(0.,0.,0.);
-    //
-    SeqPnt2d.Clear();
-    anIndexMap.Clear();
-    aD1Prev.Clear();
-    aD1Next.Clear();
-    //
-    // NbEdges
-    NbEdges=0;
-    aExp.Init(aW, TopAbs_EDGE);
-    for(; aExp.More(); aExp.Next()) { 
-      NbEdges++;
-    }
-    //
-    aWExp.Init(aW, Face);
-    for(;aWExp.More(); aWExp.Next()) {
-      NbEdges--;
-      edge = aWExp.Current();
-      Or = edge.Orientation();
-      if(!(Or==TopAbs_FORWARD || Or==TopAbs_REVERSED)) {
-        continue;
-      }
-      //
-      aC2D=BRep_Tool::CurveOnSurface(edge, Face, pfbid, plbid);
-      if (aC2D.IsNull()) {
-        return;
-      }
-      //
-      BRepAdaptor_Curve2d C(edge,Face);
-      BRepAdaptor_Curve C3d;
-      //------------------------------------------
-      degenerated=Standard_False;
-      if(BRep_Tool::Degenerated(edge) ||
-         BRep_Tool::IsClosed(edge, Face)) {
-        degenerated=Standard_True;
-      }
-      //
-      TopExp::Vertices(edge,Va,Vb);
-      //
-      TolVertex1=0.;
-      TolVertex=0.;
-      if (Va.IsNull()) {
-        degenerated=Standard_True;
-      }        
-      else {
-        TolVertex1=BRep_Tool::Tolerance(Va);
-      }
-      if (Vb.IsNull()){
-        degenerated=Standard_True;
-      }        
-      else {
-        TolVertex=BRep_Tool::Tolerance(Vb);
-      }
-        // 
-      if(TolVertex<TolVertex1) {
-        TolVertex=TolVertex1;
-      }        
-      //
-      //-- Verification of cases when forgotten to code degenereted
-      if(!degenerated) {
-        // check that whole curve is located in vicinity of its middle point
-        // (within sphere of Precision::Confusion() diameter)
-        C3d.Initialize (edge, Face);
-        gp_Pnt P3da = C3d.Value (0.5 * (pfbid + plbid));
-        du = plbid - pfbid;
-        const int NBSTEPS = 10;
-        Standard_Real aPrec2 = 0.25 * Precision::Confusion() * Precision::Confusion();
-        degenerated = Standard_True;
-        for (Standard_Integer i=0; i <= NBSTEPS; i++)
-        {
-          Standard_Real U = pfbid + i * du / NBSTEPS;
-          gp_Pnt P3db = C3d.Value (U);
-          Standard_Real aR2 = P3da.SquareDistance (P3db);
-          if (aR2 > aPrec2) {
-            degenerated = Standard_False;
-            break;
-          }
-        }
-      }//if(!degenerated)
-      //-- ----------------------------------------
-      Tole = BRep_Tool::Tolerance(edge);
-      if(Tole>Tol) {
-        Tol=Tole;
-      }
-      //
-      // NbSamples +> nbs
-      nbs = Geom2dInt_Geom2dCurveTool::NbSamples(C);
-      if (nbs > 2) {
-        nbs*=4;
-      }
-      du = (plbid-pfbid)/(Standard_Real)(nbs-1);
-      //
-      if(Or==TopAbs_FORWARD) { 
-        u = pfbid;
-        uFirst=pfbid;
-        uLast=plbid;
-      }
-      else { 
-        u = plbid;
-        uFirst=plbid;
-        uLast=pfbid;
-        du=-du;
-      }
-      //
-      // aPrms
-      aNbs1=nbs+1;
-      TColStd_Array1OfReal aPrms(1, aNbs1);
-      //
-      if (nbs==2) {
-        Standard_Real aCoef=0.0025;
-        aPrms(1)=uFirst;
-        aPrms(2)=uFirst+aCoef*(uLast-uFirst);
-        aPrms(3)=uLast;
-      }
-      else if (nbs>2) {
-        aNbs1=nbs;
-        aPrms(1)=uFirst;
-        for (iX=2; iX<aNbs1; ++iX) {
-          aPrms(iX)=u+(iX-1)*du;
-        }
-        aPrms(aNbs1)=uLast;
-      }
-      //
-      //-- ------------------------------------------------------------
-      //-- Check distance uv between the start point of the edge
-      //-- and the last point saved in SeqPnt2d
-      //-- To to set the first point of the current 
-      //-- afar from the last saved point
-      Avant = nbpnts;
-      for(iX=firstpoint; iX<=aNbs1; iX++) {
-        Standard_Boolean IsRealCurve3d;
-        Standard_Integer ii;
-        Standard_Real aDstX;
-        gp_Pnt2d P2d;
-        gp_Pnt P3d;
-        //
-        u=aPrms(iX);
-        P2d = C.Value(u);
-        if(P2d.X()<Umin) Umin = P2d.X();
-        if(P2d.X()>Umax) Umax = P2d.X();
-        if(P2d.Y()<Vmin) Vmin = P2d.Y();
-        if(P2d.Y()>Vmax) Vmax = P2d.Y();
-        //
-        aDstX=RealLast();        
-        if(degenerated==Standard_False) { 
-          P3d=C3d.Value(u);
-          if(nbpnts>1) {
-            if(Ancienpnt3dinitialise) { 
-              aDstX=P3d.SquareDistance(Ancienpnt3d);
-            }
-          }
-        }
-        //
-        IsRealCurve3d = Standard_True; 
-        if (aDstX < aPrCf2)  {
-          if(iX>1) {
-            Standard_Real aDstX1;
-            gp_Pnt MidP3d;
-            //
-            MidP3d = C3d.Value(0.5*(u+aPrms(iX-1)));
-            aDstX1=P3d.SquareDistance( MidP3d );
-            if (aDstX1 < aPrCf2){
-              IsRealCurve3d = Standard_False;
-            }
-          }
-        }
-        //
-        if (IsRealCurve3d) {
-          if(degenerated==Standard_False) { 
-            Ancienpnt3d=P3d;
-            Ancienpnt3dinitialise=Standard_True;
-          }
-          nbpnts++;
-          SeqPnt2d.Append(P2d);
-        }
-        //
-        ii=nbpnts;
-        if(ii>(Avant+4)) { 
-          Standard_Real ul, dU, dV;
-          gp_Pnt2d Pp;
-          //
-          gp_Lin2d Lin(SeqPnt2d(ii-2),gp_Dir2d(gp_Vec2d(SeqPnt2d(ii-2),SeqPnt2d(ii))));
-          ul = ElCLib::Parameter(Lin,SeqPnt2d(ii-1));
-          Pp = ElCLib::Value(ul,Lin);
-          dU = Abs(Pp.X()-SeqPnt2d(ii-1).X());
-          dV = Abs(Pp.Y()-SeqPnt2d(ii-1).Y());
-          if(dU>FlecheU) {
-            FlecheU = dU;
-          }
-          if(dV>FlecheV) {
-            FlecheV = dV;
-          }
-        }
-      }// for(iX=firstpoint; iX<=aNbs1; iX++) {
-      //
-      if(BadWire) {
-        continue; //if face has several wires and one of them is bad,
-                  //it is necessary to process all of them for correct
-                  //calculation of Umin, Umax, Vmin, Vmax - ifv, 23.08.06 
-      }
-      //
-      if(firstpoint==1) firstpoint=2;
-      WireIsNotEmpty = Standard_True;
-      // Append the derivative of the first parameter.
-      Standard_Real aU = aPrms(1);
-      gp_Pnt2d      aP;
-      gp_Vec2d      aV;
-
-      C.D1(aU, aP, aV);
-
-      if(Or == TopAbs_REVERSED)
-        aV.Reverse();
-
-      aD1Next.Append(aV);
-
-      // Append the derivative of the last parameter.
-      aU = aPrms(aNbs1);
-      C.D1(aU, aP, aV);
-
-      if(Or == TopAbs_REVERSED)
-        aV.Reverse();
-
-      if (NbEdges > 0)
-        aD1Prev.Append(aV);
-      else
-        aD1Prev.Prepend(aV);
-
-      // Fill the map anIndexMap.
-      if (Avant > 0)
-        anIndexMap.Bind(Avant, aD1Next.Length());
-      else
-        anIndexMap.Bind(1, aD1Next.Length());
-    } //for(;aWExp.More(); aWExp.Next()) {
-    // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-    //
-    if(NbEdges) { 
-      //-- count ++ with normal explorer and -- with Wire Explorer
-      TColgp_Array1OfPnt2d PClass(1,2);
-      gp_Pnt2d anInitPnt(0., 0.);
-      //
-      PClass.Init(anInitPnt);
-      TabClass.Append((void *)new CSLib_Class2d(PClass,
-						FlecheU,
-						FlecheV,
-						Umin,Vmin,Umax,Vmax));
-      BadWire=1;
-      TabOrien.Append(-1);
-    }
-    //
-    else if(WireIsNotEmpty) { 
-      TColgp_Array1OfPnt2d PClass(1,nbpnts);
-      gp_Pnt2d anInitPnt(0., 0.);
-      //
-      PClass.Init(anInitPnt);
-      if(nbpnts>3) { 
-        Standard_Integer im2=nbpnts-2;
-        Standard_Integer im1=nbpnts-1;
-        Standard_Integer im0=1;
-        Standard_Real    angle = 0.0;
-        Standard_Real aX0, aY0, aX1, aY1, aS;
-        //
-        aS=0.;
-        //
-        Standard_Integer iFlag=1;
-	//
-        PClass(im2)=SeqPnt2d.Value(im2);
-        PClass(im1)=SeqPnt2d.Value(im1);
-        PClass(nbpnts)=SeqPnt2d.Value(nbpnts);
-        Standard_Real aPer = 0.;
-        for (Standard_Integer ii = 1; ii<nbpnts; ii++, im0++, im1++, im2++)
-        {
-          if(im2>=nbpnts) im2=1;
-          if(im1>=nbpnts) im1=1;
-          PClass(ii)=SeqPnt2d.Value(ii);
-          //
-          const gp_Pnt2d& aP2D1=PClass(im1);
-          const gp_Pnt2d& aP2D0=PClass(im0);
-          //aP2D0 is next to aP2D1
-          aP2D0.Coord(aX0, aY0);
-          aP2D1.Coord(aX1, aY1);
-          aS=aS+(aY0+aY1)*(aX1-aX0); 
-          aPer += aP2D1.Distance(aP2D0);
-
-          gp_Vec2d A(PClass(im2),PClass(im1));
-          gp_Vec2d B(PClass(im1),PClass(im0));
-
-          Standard_Real N = A.Magnitude() * B.Magnitude();
-          if(N>1e-16) { 
-            Standard_Real a=A.Angle(B);
-            //  
-            if (anIndexMap.IsBound(im1)) {
-              Standard_Integer  anInd  = anIndexMap.Find(im1);
-              const gp_Vec2d   &aVPrev = aD1Prev.Value(anInd);
-              const gp_Vec2d   &aVNext = aD1Next.Value(anInd);
-
-              Standard_Real aN = aVPrev.Magnitude() * aVNext.Magnitude();
-              if(aN > 1e-16) { 
-                Standard_Real aDerivAngle, aAbsDA, aProduct, aPA;
-                //ifv 23.08.06
-		aPA=Precision::Angular();
-		aDerivAngle = aVPrev.Angle(aVNext);
-		aAbsDA=Abs(aDerivAngle);
-                if(aAbsDA <= aPA) {
-		  aDerivAngle = 0.; 
-		}
-		//
-		aProduct=aDerivAngle * a;
-		//
-	        if(Abs(aAbsDA - M_PI) <= aPA) {
-		  if (aProduct > 0.) {
-		    aProduct=-aProduct; 
-		  }
-		}
-                //ifv 23.08.06 : if edges continuity > G1, |aDerivAngle| ~0,
-                //but can has wrong sign and causes condition aDerivAngle * a < 0.
-                //that is wrong in such situation
-                if (iFlag && aProduct < 0.) {
-                  iFlag=0;
-                  // Bad case.
-                  angle = 0.;
-                }
-              }
-            }
-            angle+=a;
-          }
-        }//for(ii=1; ii<nbpnts; ii++,im0++,im1++,im2++) { 
-        if (!iFlag) {
-          angle = 0.; 
-        }
-#ifdef DEBUG_PCLASS_POLYGON
-        TColStd_Array1OfReal aKnots(1, nbpnts);
-        TColStd_Array1OfInteger aMults(1, nbpnts);
-        for (int i = 1; i <= nbpnts; i++)
-        {
-          aKnots(i) = i;
-          aMults(i) = 1;
-        }
-        aMults(1) = aMults(nbpnts) = 2;
-        Handle(Geom2d_BSplineCurve) aPol = new Geom2d_BSplineCurve(PClass, aKnots, aMults, 1);
-        DrawTrSurf::Set("pol", aPol);
-#endif
-
-        Standard_Real anExpThick = Max(2. * Abs(aS) / aPer, 1e-7);
-        Standard_Real aDefl = Max(FlecheU, FlecheV);
-        Standard_Real aDiscrDefl = Min(aDefl*0.1, anExpThick * 10.);
-        while (aDefl > anExpThick && aDiscrDefl > 1e-7)
-        {
-          // Deflection of the polygon is too much for this ratio of area and perimeter,
-          // and this might lead to self-intersections.
-          // Discretize the wire more tightly to eliminate the error.
-          firstpoint = 1;
-          SeqPnt2d.Clear();
-          FlecheU = 0.0;
-          FlecheV = 0.0;
-          for (aWExp.Init(TopoDS::Wire(aExpF.Current()), Face);
-            aWExp.More(); aWExp.Next())
-          {
-            edge = aWExp.Current();
-            Or = edge.Orientation();
-            if (Or == TopAbs_FORWARD || Or == TopAbs_REVERSED)
-            {
-              BRep_Tool::Range(edge, Face, pfbid, plbid);
-              if (Abs(plbid - pfbid) < 1.e-9) continue;
-              BRepAdaptor_Curve2d C(edge, Face);
-              GCPnts_QuasiUniformDeflection aDiscr(C, aDiscrDefl);
-              if (!aDiscr.IsDone())
-                break;
-              Standard_Integer nbp = aDiscr.NbPoints();
-              Standard_Integer iStep = 1, i = 1, iEnd = nbp + 1;
-              if (Or == TopAbs_REVERSED)
-              {
-                iStep = -1;
-                i = nbp;
-                iEnd = 0;
-              }
-              if (firstpoint == 2)
-                i += iStep;
-              for (; i != iEnd; i += iStep)
-              {
-                gp_Pnt2d aP2d = C.Value(aDiscr.Parameter(i));
-                SeqPnt2d.Append(aP2d);
-              }
-              if (nbp > 2)
-              {
-                Standard_Integer ii = SeqPnt2d.Length();
-                gp_Lin2d Lin(SeqPnt2d(ii - 2), gp_Dir2d(gp_Vec2d(SeqPnt2d(ii - 2), SeqPnt2d(ii))));
-                Standard_Real ul = ElCLib::Parameter(Lin, SeqPnt2d(ii - 1));
-                gp_Pnt2d Pp = ElCLib::Value(ul, Lin);
-                Standard_Real dU = Abs(Pp.X() - SeqPnt2d(ii - 1).X());
-                Standard_Real dV = Abs(Pp.Y() - SeqPnt2d(ii - 1).Y());
-                if (dU > FlecheU) FlecheU = dU;
-                if (dV > FlecheV) FlecheV = dV;
-              }
-              firstpoint = 2;
-            }
-          }
-          nbpnts = SeqPnt2d.Length();
-          PClass.Resize(1, nbpnts, Standard_False);
-          im1 = nbpnts - 1;
-          im0 = 1;
-          PClass(im1) = SeqPnt2d.Value(im1);
-          PClass(nbpnts) = SeqPnt2d.Value(nbpnts);
-          aS = 0.;
-          aPer = 0.;
-          for (Standard_Integer ii = 1; ii<nbpnts; ii++, im0++, im1++)
-          {
-            if (im1 >= nbpnts) im1 = 1;
-            PClass(ii) = SeqPnt2d.Value(ii);
-            aS += (PClass(im1).X() - PClass(im0).X())*(PClass(im0).Y() + PClass(im1).Y())*.5;
-            aPer += (PClass(im0).XY() - PClass(im1).XY()).Modulus();
-          }
-#ifdef DEBUG_PCLASS_POLYGON
-          TColStd_Array1OfReal aKnots(1, nbpnts);
-          TColStd_Array1OfInteger aMults(1, nbpnts);
-          for (int i = 1; i <= nbpnts; i++)
-          {
-            aKnots(i) = i;
-            aMults(i) = 1;
-          }
-          aMults(1) = aMults(nbpnts) = 2;
-          Handle(Geom2d_BSplineCurve) aPol = new Geom2d_BSplineCurve(PClass, aKnots, aMults, 1);
-          DrawTrSurf::Set("pol1", aPol);
-#endif
-
-          anExpThick = Max(2. * Abs(aS) / aPer, 1e-7);
-          aDefl = Max(FlecheU, FlecheV);
-          aDiscrDefl = Min(aDiscrDefl * 0.1, anExpThick * 10.);
-        }
-
-        if(aS>0.){
-          myIsHole=Standard_False;
-        }
-        //
-        if(FlecheU<Toluv)
-          FlecheU = Toluv;
-
-        if(FlecheV<Toluv)
-          FlecheV = Toluv;
-
-        TabClass.Append((void *)new CSLib_Class2d(PClass,
-						  FlecheU,
-						  FlecheV,
-						  Umin,Vmin,Umax,Vmax));
-        //
-        if((angle<2 && angle>-2)||(angle>10)||(angle<-10)) { 
-          BadWire=1;
-          TabOrien.Append(-1);
-        } 
-        else {         
-          TabOrien.Append((angle>0.0)? 1 : 0);
-        }
-      } 
-      else { 
-        BadWire=1;
-        TabOrien.Append(-1);
-        TColgp_Array1OfPnt2d PPClass(1,2);
-        PPClass.Init(anInitPnt);
-        TabClass.Append((void *)new CSLib_Class2d(PPClass,
-						  FlecheU,
-						  FlecheV,
-						  Umin,Vmin,Umax,Vmax));
-      }
-    }// else if(WireIsNotEmpty)
-  } // for(; aExpF.More();  aExpF.Next()) {
-  //
-  Standard_Integer nbtabclass = TabClass.Length();
-  //
-  if(nbtabclass>0) { 
-    //-- if an error on a wire was detected : all TabOrien set to -1
-    if(BadWire) {
-      TabOrien(1)=-1;
-    }
-    
-    if(   surf->GetType()==GeomAbs_Cone
-       || surf->GetType()==GeomAbs_Cylinder
-       || surf->GetType()==GeomAbs_Torus
-       || surf->GetType()==GeomAbs_Sphere
-       || surf->GetType()==GeomAbs_SurfaceOfRevolution) { 
-      Standard_Real uuu=M_PI+M_PI-(Umax-Umin);
-      if(uuu<0) uuu=0;
-      U1 = Umin-uuu*0.5;
-      U2 = U1+M_PI+M_PI;
-    }
-    else { 
-      U1=U2=0.0; 
-    } 
-    
-    if(surf->GetType()==GeomAbs_Torus) { 
-      Standard_Real uuu=M_PI+M_PI-(Vmax-Vmin);
-      if(uuu<0) uuu=0;
-      
-      V1 = Vmin-uuu*0.5;
-      V2 = V1+M_PI+M_PI;
-    }
-    else { 
-      V1=V2=0.0; 
-    }   
-  }
-}
-//=======================================================================
-//function : PerformInfinitePoint
-//purpose  : 
-//=======================================================================
-TopAbs_State IntTools_FClass2d::PerformInfinitePoint() const 
-{ 
-  if(Umax==-RealLast() || Vmax==-RealLast() || 
-     Umin==RealLast() || Vmin==RealLast()) { 
-    return(TopAbs_IN);
-  }
-  gp_Pnt2d P(Umin-(Umax-Umin),Vmin-(Vmax-Vmin));
-  return(Perform(P,Standard_False));
-}
-//=======================================================================
-//function : Perform
-//purpose  : 
-//=======================================================================
-TopAbs_State IntTools_FClass2d::Perform
-  (const gp_Pnt2d& _Puv,
-   const Standard_Boolean RecadreOnPeriodic) const
-{ 
-  Standard_Integer nbtabclass = TabClass.Length();
-  if (nbtabclass == 0)
-  {
-    return TopAbs_IN;
-  }
-
-  //-- U1 is the First Param and U2 is in this case U1+Period
-  Standard_Real u = _Puv.X();
-  Standard_Real v = _Puv.Y();
-  Standard_Real uu = u;
-  Standard_Real vv = v;
-  TopAbs_State aStatus = TopAbs_UNKNOWN;
-
-  Handle(BRepAdaptor_HSurface) surf = new BRepAdaptor_HSurface();
-  surf->ChangeSurface().Initialize( Face, Standard_False );
-  
-  const Standard_Boolean IsUPer  = surf->IsUPeriodic();
-  const Standard_Boolean IsVPer  = surf->IsVPeriodic();
-  const Standard_Real    uperiod = IsUPer ? surf->UPeriod() : 0.0;
-  const Standard_Real    vperiod = IsVPer ? surf->VPeriod() : 0.0;
-
-  Standard_Boolean urecadre, vrecadre, bUseClassifier;
-  Standard_Integer dedans = 1;
-  //
-  urecadre = Standard_False;
-  vrecadre = Standard_False;
-  //
-  if (RecadreOnPeriodic) {
-    Standard_Real du, dv;
-    if (IsUPer) {
-      GeomInt::AdjustPeriodic(uu, Umin, Umax, uperiod, uu, du);
-    }// if (IsUPer) {
-    //
-    if (IsVPer) {
-      GeomInt::AdjustPeriodic(vv, Vmin, Vmax, vperiod, vv, dv);
-    }//if (IsVPer) {
-  }
-  //
-  for(;;) {
-    dedans = 1;
-    gp_Pnt2d Puv(u,v);
-    bUseClassifier = (TabOrien(1) == -1);
-    if(!bUseClassifier) {
-      Standard_Integer n, cur, TabOrien_n ;
-      for(n=1; n<=nbtabclass; n++) { 
-        cur = ((CSLib_Class2d *)TabClass(n))->SiDans(Puv);
-        TabOrien_n=TabOrien(n);
-        
-        if(cur==1) { 
-          if(TabOrien_n==0) { 
-            dedans = -1; 
-            break;
-          }
-        }
-        else if(cur==-1) { 
-          if(TabOrien_n==1) {  
-            dedans = -1; 
-            break;
-          }
-        }
-        else { 
-          dedans = 0;
-          break;
-        }
-      } // for(n=1; n<=nbtabclass; n++)
-      
-      if(dedans==0) { 
-        bUseClassifier = Standard_True;
-      } 
-      else {
-        aStatus = (dedans == 1) ? TopAbs_IN : TopAbs_OUT;
-      }
-    } // if(TabOrien(1)!=-1) {
-    //compute state of the point using face classifier
-    if (bUseClassifier) {
-      //compute tolerance to use in face classifier
-      Standard_Real aURes, aVRes, aFCTol;
-      Standard_Boolean bUIn, bVIn;
-      //
-      aURes = surf->UResolution(Toluv);
-      aVRes = surf->VResolution(Toluv);
-      //
-      bUIn = (u >= Umin) && (u <= Umax);
-      bVIn = (v >= Vmin) && (v <= Vmax);
-      //
-      if (bUIn==bVIn) {
-	aFCTol = Min(aURes, aVRes);
-      }
-      else {
-	aFCTol = (!bUIn) ? aURes : aVRes;
-      }
-      //
-      BRepClass_FaceClassifier aClassifier;
-      aClassifier.Perform(Face,Puv,aFCTol);
-      aStatus = aClassifier.State();
-    }
-    
-    if (!RecadreOnPeriodic || (!IsUPer && !IsVPer))
-      return aStatus;
-    
-    if (aStatus == TopAbs_IN || aStatus == TopAbs_ON)
-      return aStatus;
-    
-    if (!urecadre){
-      u = uu;
-      urecadre = Standard_True;
-    }
-    else {
-      if (IsUPer){
-        u += uperiod;
-      }
-    }
-
-    if (u > Umax || !IsUPer) {
-      if (!vrecadre){
-        v = vv;
-        vrecadre = Standard_True;
-      }
-      else {
-        if (IsVPer){
-          v += vperiod;
-        }
-      }
-
-      u = uu;
-      
-      if (v > Vmax || !IsVPer) {
-        return aStatus;
-      }
-    }
-  } //while (1)
-}
-
-//=======================================================================
-//function : TestOnRestriction
-//purpose  : 
-//=======================================================================
-TopAbs_State IntTools_FClass2d::TestOnRestriction
-  (const gp_Pnt2d& _Puv,
-   const Standard_Real Tol,
-   const Standard_Boolean RecadreOnPeriodic) const
-{ 
-  Standard_Integer nbtabclass = TabClass.Length();
-  if (nbtabclass == 0)
-  {
-    return TopAbs_IN;
-  }
-
-  //-- U1 is the First Param and U2 in this case is U1+Period
-  Standard_Real u=_Puv.X();
-  Standard_Real v=_Puv.Y();
-  Standard_Real uu = u, vv = v;
-
-  Handle(BRepAdaptor_HSurface) surf = new BRepAdaptor_HSurface();
-  surf->ChangeSurface().Initialize( Face, Standard_False );
-  const Standard_Boolean IsUPer  = surf->IsUPeriodic();
-  const Standard_Boolean IsVPer  = surf->IsVPeriodic();
-  const Standard_Real    uperiod = IsUPer ? surf->UPeriod() : 0.0;
-  const Standard_Real    vperiod = IsVPer ? surf->VPeriod() : 0.0;
-  TopAbs_State aStatus = TopAbs_UNKNOWN;
-  Standard_Boolean urecadre = Standard_False, vrecadre = Standard_False;
-  Standard_Integer dedans = 1;
-
-  if (RecadreOnPeriodic) {
-    Standard_Real du, dv;
-    if (IsUPer) {
-      GeomInt::AdjustPeriodic(uu, Umin, Umax, uperiod, uu, du);
-    }// if (IsUPer) {
-    //
-    if (IsVPer) {
-      GeomInt::AdjustPeriodic(vv, Vmin, Vmax, vperiod, vv, dv);
-    }//if (IsVPer) {
-  }
-  //
-  for (;;) {
-    dedans = 1;
-    gp_Pnt2d Puv(u,v);
-    
-    if(TabOrien(1)!=-1) { 
-      for(Standard_Integer n=1; n<=nbtabclass; n++) { 
-        Standard_Integer cur = ((CSLib_Class2d *)TabClass(n))->SiDans_OnMode(Puv,Tol);
-        if(cur==1) { 
-          if(TabOrien(n)==0) { 
-            dedans = -1; 
-            break;
-          }
-        }
-        else if(cur==-1) { 
-          if(TabOrien(n)==1) {  
-            dedans = -1; 
-            break;
-          }
-        }
-        else { 
-          dedans = 0;
-          break;
-        }
-      }
-      if(dedans==0) {
-        aStatus = TopAbs_ON;
-      }
-      if(dedans == 1) {
-        aStatus = TopAbs_IN;
-      }
-      if(dedans == -1) {
-        aStatus = TopAbs_OUT;
-      }
-    }
-    else {  //-- TabOrien(1)=-1  Wrong  Wire 
-      BRepClass_FaceClassifier aClassifier;
-      aClassifier.Perform(Face,Puv,Tol);
-      aStatus = aClassifier.State();
-    }
-    
-    if (!RecadreOnPeriodic || (!IsUPer && !IsVPer))
-      return aStatus;
-    if (aStatus == TopAbs_IN || aStatus == TopAbs_ON)
-      return aStatus;
-    
-    if (!urecadre)
-      {
-        u = uu;
-        urecadre = Standard_True;
-      }
-    else
-      if (IsUPer)
-        u += uperiod;
-    if (u > Umax || !IsUPer)
-      {
-        if (!vrecadre)
-          {
-            v = vv;
-            vrecadre = Standard_True;
-          }
-        else
-          if (IsVPer)
-            v += vperiod;
-        
-        u = uu;
-        
-        if (v > Vmax || !IsVPer)
-          return aStatus;
-      }
-  } //for (;;)
-}
-//=======================================================================
-//function : Destroy
-//purpose  : 
-//=======================================================================
-void IntTools_FClass2d::Destroy() 
-{ 
-  Standard_Integer nbtabclass = TabClass.Length(); 
-  for(Standard_Integer d=1; d<=nbtabclass;d++) {
-    if(TabClass(d)) { 
-      delete ((CSLib_Class2d *)TabClass(d));
-      TabClass(d)=NULL;
-    }
-  }
-}
-
-
diff --git a/src/IntTools/IntTools_FClass2d.hxx b/src/IntTools/IntTools_FClass2d.hxx
deleted file mode 100644
index 1d0b0a4..0000000
--- a/src/IntTools/IntTools_FClass2d.hxx
+++ /dev/null
@@ -1,120 +0,0 @@
-// Created on: 1995-03-22
-// Created by: Laurent BUCHARD
-// Copyright (c) 1995-1999 Matra Datavision
-// Copyright (c) 1999-2014 OPEN CASCADE SAS
-//
-// This file is part of Open CASCADE Technology software library.
-//
-// This library is free software; you can redistribute it and/or modify it under
-// the terms of the GNU Lesser General Public License version 2.1 as published
-// by the Free Software Foundation, with special exception defined in the file
-// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
-// distribution for complete text of the license and disclaimer of any warranty.
-//
-// Alternatively, this file may be used under the terms of Open CASCADE
-// commercial license or contractual agreement.
-
-#ifndef _IntTools_FClass2d_HeaderFile
-#define _IntTools_FClass2d_HeaderFile
-
-#include <Standard.hxx>
-#include <Standard_DefineAlloc.hxx>
-#include <Standard_Handle.hxx>
-
-#include <BRepTopAdaptor_SeqOfPtr.hxx>
-#include <TColStd_SequenceOfInteger.hxx>
-#include <Standard_Real.hxx>
-#include <TopoDS_Face.hxx>
-#include <Standard_Boolean.hxx>
-#include <TopAbs_State.hxx>
-class TopoDS_Face;
-class gp_Pnt2d;
-
-
-//! Class provides an algorithm to classify a 2d Point
-//! in 2d space of face using boundaries of the face.
-class IntTools_FClass2d 
-{
-public:
-
-  DEFINE_STANDARD_ALLOC
-
-  
-
-  //! Empty constructor
-  Standard_EXPORT IntTools_FClass2d();
-  
-
-  //! Initializes algorithm by the face F
-  //! and tolerance Tol
-  Standard_EXPORT IntTools_FClass2d(const TopoDS_Face& F, const Standard_Real Tol);
-  
-
-  //! Initializes algorithm by the face F
-  //! and tolerance Tol
-  Standard_EXPORT void Init (const TopoDS_Face& F, const Standard_Real Tol);
-  
-
-  //! Returns state of infinite 2d point relatively to (0, 0)
-  Standard_EXPORT TopAbs_State PerformInfinitePoint() const;
-  
-
-  //! Returns state of the 2d point Puv.
-  //! If RecadreOnPeriodic is true (defalut value),
-  //! for the periodic surface 2d point, adjusted to period, is
-  //! classified.
-  Standard_EXPORT TopAbs_State Perform (const gp_Pnt2d& Puv, const Standard_Boolean RecadreOnPeriodic = Standard_True) const;
-  
-
-  //! Destructor
-  Standard_EXPORT void Destroy();
-~IntTools_FClass2d()
-{
-  Destroy();
-}
-  
-
-  //! Test a point with +- an offset (Tol) and returns
-  //! On if some points are OUT an some are IN
-  //! (Caution: Internal use . see the code for more details)
-  Standard_EXPORT TopAbs_State TestOnRestriction (const gp_Pnt2d& Puv, const Standard_Real Tol, const Standard_Boolean RecadreOnPeriodic = Standard_True) const;
-  
-  Standard_EXPORT Standard_Boolean IsHole() const;
-
-
-
-
-protected:
-
-
-
-
-
-private:
-
-
-
-  BRepTopAdaptor_SeqOfPtr TabClass;
-  TColStd_SequenceOfInteger TabOrien;
-  Standard_Real Toluv;
-  TopoDS_Face Face;
-  Standard_Real U1;
-  Standard_Real V1;
-  Standard_Real U2;
-  Standard_Real V2;
-  Standard_Real Umin;
-  Standard_Real Umax;
-  Standard_Real Vmin;
-  Standard_Real Vmax;
-  Standard_Boolean myIsHole;
-
-
-};
-
-
-
-
-
-
-
-#endif // _IntTools_FClass2d_HeaderFile
diff --git a/src/IntTools/IntTools_FaceFace.cxx b/src/IntTools/IntTools_FaceFace.cxx
index 96d14a6..de91078 100644
--- a/src/IntTools/IntTools_FaceFace.cxx
+++ b/src/IntTools/IntTools_FaceFace.cxx
@@ -493,10 +493,10 @@ void IntTools_FaceFace::Perform(const TopoDS_Face& aF1,
     myHS2->ChangeSurface().Load(S2, umin, umax, vmin, vmax);
   }
 
-  const Handle(IntTools_TopolTool) dom1 = new IntTools_TopolTool(myHS1);
-  const Handle(IntTools_TopolTool) dom2 = new IntTools_TopolTool(myHS2);
+  const Handle(IntTools_TopolTool) aDom1 = new IntTools_TopolTool(myHS1);
+  const Handle(IntTools_TopolTool) aDom2 = new IntTools_TopolTool(myHS2);
 
-  myLConstruct.Load(dom1, dom2, myHS1, myHS2);
+  myLConstruct.Load(aDom1, aDom2, myHS1, myHS2);
   
 
   Tolerances(myHS1, myHS2, TolTang);
@@ -545,9 +545,9 @@ void IntTools_FaceFace::Perform(const TopoDS_Face& aF1,
 
   const Standard_Boolean isGeomInt = isTreatAnalityc(aBAS1, aBAS2, myTol);
   if (aF1.IsSame(aF2))
-    myIntersector.Perform(myHS1, dom1, TolArc, TolTang);
+    myIntersector.Perform(myHS1, aDom1, TolArc, TolTang);
   else
-    myIntersector.Perform(myHS1, dom1, myHS2, dom2, TolArc, TolTang, 
+    myIntersector.Perform(myHS1, aDom1, myHS2, aDom2, TolArc, TolTang, 
                           myListOfPnts, isGeomInt);
 
   myIsDone = myIntersector.IsDone();
@@ -561,7 +561,7 @@ void IntTools_FaceFace::Perform(const TopoDS_Face& aF1,
     //
     const Standard_Integer aNbLinIntersector = myIntersector.NbLines();
     for (Standard_Integer i=1; i <= aNbLinIntersector; ++i) {
-      MakeCurve(i, dom1, dom2, TolArc);
+      MakeCurve(i, aDom1, aDom2, TolArc);
     }
     //
     ComputeTolReached3d();
@@ -704,8 +704,8 @@ void IntTools_FaceFace::ComputeTolReached3d()
 //purpose  : 
 //=======================================================================
 void IntTools_FaceFace::MakeCurve(const Standard_Integer Index,
-                                  const Handle(Adaptor3d_TopolTool)& dom1,
-                                  const Handle(Adaptor3d_TopolTool)& dom2,
+                                  const Handle(Adaptor3d_TopolTool)& theDom1,
+                                  const Handle(Adaptor3d_TopolTool)& theDom2,
                                   const Standard_Real theToler) 
 {
   Standard_Boolean bDone, rejectSurface, reApprox, bAvoidLineConstructor;
@@ -870,13 +870,12 @@ void IntTools_FaceFace::MakeCurve(const Standard_Integer Index,
           continue;
         }
 
-        Standard_Real u1, v1, u2, v2, Tol;
-        
-        Tol = Precision::Confusion();
+        Standard_Real u1, v1, u2, v2;
+
         Parameters(myHS1, myHS2, ptref,  u1, v1, u2, v2);
-        ok = (dom1->Classify(gp_Pnt2d(u1, v1), Tol) != TopAbs_OUT);
+        ok = (theDom1->Classify(gp_Pnt2d(u1, v1), Precision::Confusion()) != TopAbs_OUT);
         if(ok) { 
-          ok = (dom2->Classify(gp_Pnt2d(u2,v2),Tol) != TopAbs_OUT); 
+          ok = (theDom2->Classify(gp_Pnt2d(u2, v2), Precision::Confusion()) != TopAbs_OUT);
         }
         if (ok) {
           Handle(Geom2d_BSplineCurve) H1;
@@ -1032,18 +1031,17 @@ void IntTools_FaceFace::MakeCurve(const Standard_Integer Index,
           }
         }
         //
-        Standard_Real aTwoPIdiv17, u1, v1, u2, v2, Tol;
+        Standard_Real aTwoPIdiv17, u1, v1, u2, v2;
 
         aTwoPIdiv17=2.*M_PI/17.;
 
         for (j=0; j<=17; j++) {
           gp_Pnt ptref (newc->Value (j*aTwoPIdiv17));
-          Tol = Precision::Confusion();
 
           Parameters(myHS1, myHS2, ptref, u1, v1, u2, v2);
-          ok = (dom1->Classify(gp_Pnt2d(u1,v1),Tol) != TopAbs_OUT);
+          ok = (theDom1->Classify(gp_Pnt2d(u1, v1), Precision::Confusion()) != TopAbs_OUT);
           if(ok) { 
-            ok = (dom2->Classify(gp_Pnt2d(u2,v2),Tol) != TopAbs_OUT);
+            ok = (theDom2->Classify(gp_Pnt2d(u2, v2), Precision::Confusion()) != TopAbs_OUT);
           }
           if (ok) {
             IntTools_Curve aCurve;
diff --git a/src/IntTools/IntTools_Tools.cxx b/src/IntTools/IntTools_Tools.cxx
index 46c891d..7c8a6d4 100644
--- a/src/IntTools/IntTools_Tools.cxx
+++ b/src/IntTools/IntTools_Tools.cxx
@@ -19,6 +19,7 @@
 #include <BRep_Tool.hxx>
 #include <BRepAdaptor_Curve.hxx>
 #include <BRepAdaptor_Surface.hxx>
+#include <BRepTopAdaptor_FClass2d.hxx>
 #include <Geom2d_Curve.hxx>
 #include <Geom2d_TrimmedCurve.hxx>
 #include <Geom_BoundedCurve.hxx>
@@ -41,7 +42,6 @@
 #include <gp_Pnt2d.hxx>
 #include <IntTools_CommonPrt.hxx>
 #include <IntTools_Curve.hxx>
-#include <IntTools_FClass2d.hxx>
 #include <IntTools_Range.hxx>
 #include <IntTools_SequenceOfCurves.hxx>
 #include <IntTools_Tools.hxx>
@@ -430,14 +430,11 @@ static
 //purpose  : 
 //=======================================================================
   TopAbs_State IntTools_Tools::ClassifyPointByFace(const TopoDS_Face& aF,
-         const gp_Pnt2d& aP2d)
+                                                   const gp_Pnt2d& aP2d)
 {
-  Standard_Real aFaceTolerance;
-  TopAbs_State aState;
-  
-  aFaceTolerance=BRep_Tool::Tolerance(aF);
-  IntTools_FClass2d aClass2d(aF, aFaceTolerance);
-  aState=aClass2d.Perform(aP2d);
+  const Standard_Real aTolF=BRep_Tool::Tolerance(aF);
+  BRepTopAdaptor_FClass2d aClass2d(aF, aTolF);
+  const TopAbs_State aState=aClass2d.Perform(aP2d);
   
   return aState;
 }
diff --git a/src/LocOpe/LocOpe_FindEdgesInFace.cxx b/src/LocOpe/LocOpe_FindEdgesInFace.cxx
index 1dbc5c9..5eb1ea1 100644
--- a/src/LocOpe/LocOpe_FindEdgesInFace.cxx
+++ b/src/LocOpe/LocOpe_FindEdgesInFace.cxx
@@ -78,7 +78,6 @@ void LocOpe_FindEdgesInFace::Set(const TopoDS_Shape& Sh,
   }
 
   Handle(BRepAdaptor_HSurface) HS = new BRepAdaptor_HSurface(myFace);
-  BRepTopAdaptor_TopolTool TPT(HS);
 
   for (exp.Init(myShape,TopAbs_EDGE); exp.More(); exp.Next()) {
     ToAdd = Standard_False;
@@ -160,13 +159,15 @@ void LocOpe_FindEdgesInFace::Set(const TopoDS_Shape& Sh,
 	else {
 	  ElSLib::Parameters(cy,p[i],U,V);
 	}
-	if (TPT.Classify(gp_Pnt2d(U,V),Precision::Confusion())== TopAbs_OUT) {
-	  break;
-	}
+        
+        BRepTopAdaptor_TopolTool aTPT(HS);
+        if (aTPT.Classify(gp_Pnt2d(U,V),Precision::Confusion())== TopAbs_OUT) {
+          break;
+        }
       }
       if (i >= 3) { 
-	M.Add(edg);
-	myList.Append(edg);
+        M.Add(edg);
+        myList.Append(edg);
       }
     }
   }
diff --git a/src/LocOpe/LocOpe_SplitShape.cxx b/src/LocOpe/LocOpe_SplitShape.cxx
index 80b896b..dcb3812 100644
--- a/src/LocOpe/LocOpe_SplitShape.cxx
+++ b/src/LocOpe/LocOpe_SplitShape.cxx
@@ -643,7 +643,7 @@ Standard_Boolean LocOpe_SplitShape::AddClosedWire(const TopoDS_Wire& W,
   //  GProp_GProps GP;
   //  BRepGProp::SurfaceProperties (newFace,GP);
   //  if (GP.Mass() < 0) {
-  BRepTopAdaptor_FClass2d classif(newFace,Precision::PConfusion());
+  BRepTopAdaptor_FClass2d classif(newFace, Precision::Confusion());
   if (classif.PerformInfinitePoint() == TopAbs_IN) {
     //le wire donne defini un trou
     aLocalFace = F.EmptyCopied();
@@ -1352,7 +1352,7 @@ static Standard_Boolean IsInside(const TopoDS_Face& F,
   //  GProp_GProps GP;
   //  BRepGProp::SurfaceProperties(newFace,GP);
   //  if (GP.Mass() < 0) {
-  BRepTopAdaptor_FClass2d classif(newFace,Precision::PConfusion());
+  BRepTopAdaptor_FClass2d classif(newFace,Precision::Confusion());
   Standard_Boolean Reversed = Standard_False;
   if (classif.PerformInfinitePoint() == TopAbs_IN) {
     //le wire donne defini un trou
@@ -1426,7 +1426,7 @@ static Standard_Boolean IsInside(const TopoDS_Face& F,
     gp_Pnt2d pt2d(C2d->Value(prm));
     //  BRepClass_FaceClassifier classif(F,pt2d,Precision::PConfusion());
     //  return (classif.State() != TopAbs_OUT);
-    BRepTopAdaptor_FClass2d classif(F,Precision::PConfusion());
+    BRepTopAdaptor_FClass2d classif(F,Precision::Confusion());
     TopAbs_State stat = classif.Perform(pt2d);
     //  return (classif.Perform(pt2d) != TopAbs_OUT);
     if(stat == TopAbs_OUT) return Standard_False;
diff --git a/src/LocOpe/LocOpe_WiresOnShape.cxx b/src/LocOpe/LocOpe_WiresOnShape.cxx
index d463cf9..e6ef814 100644
--- a/src/LocOpe/LocOpe_WiresOnShape.cxx
+++ b/src/LocOpe/LocOpe_WiresOnShape.cxx
@@ -1516,7 +1516,7 @@ Standard_Boolean LocOpe_WiresOnShape::Add(const TopTools_SequenceOfShape& theEdg
 
         if (aCheckStateTool.IsNull())
         {
-          aCheckStateTool = new BRepTopAdaptor_FClass2d(aCurF, Precision::PConfusion());
+          aCheckStateTool = new BRepTopAdaptor_FClass2d(aCurF, Precision::Confusion());
         }
         if (aCheckStateTool->Perform(gp_Pnt2d(aU, aV)) == TopAbs_IN)
         {
diff --git a/src/QABugs/QABugs_11.cxx b/src/QABugs/QABugs_11.cxx
index 03b79bb..269c93d 100644
--- a/src/QABugs/QABugs_11.cxx
+++ b/src/QABugs/QABugs_11.cxx
@@ -1095,96 +1095,6 @@ static Standard_Integer OCC363 (Draw_Interpretor& di, Standard_Integer argc, con
 //  return 0;
 //}
 
-#include <BRepTopAdaptor_FClass2d.hxx>
-
-//======================================================================================
-// Function : OCC377
-// Purpose  :
-//======================================================================================
-static Standard_Integer OCC377 (Draw_Interpretor& di, Standard_Integer argc, const char ** argv)
-{
-  try
-  {
-    OCC_CATCH_SIGNALS
-    // 1. Verify validity of arguments
-    if ( argc < 1 ) {di << "Error OCC377. Use  OCC377 file x y precuv \n";return 0;}
-
-    // 2. Initialize parameters
-    gp_Pnt2d p2d;
-    p2d.SetX ( Draw::Atof(argv[2]) );
-    p2d.SetY ( Draw::Atof(argv[3]) );
-    Standard_Real precuv = Draw::Atof (argv[4] );
-
-    // 3. Read shape
-    BRep_Builder B;
-    TopoDS_Shape Shape;
-    BRepTools::Read ( Shape, argv[1], B );
-
-    // 4. Verify whether enrtry point is on wire and reversed ones (indeed results of veridying must be same)
-    TopExp_Explorer exp;
-    Standard_Integer i=1;
-    for (exp.Init(Shape.Oriented(TopAbs_FORWARD),TopAbs_WIRE); exp.More(); exp.Next(), i++)
-    {
-      // 4.1. Verify whether enrtry point is on wire
-      const TopoDS_Wire& wir = TopoDS::Wire(exp.Current());
-      TopoDS_Face newFace = TopoDS::Face(Shape.EmptyCopied());
-
-      TopAbs_Orientation orWire = wir.Orientation();
-      newFace.Orientation(TopAbs_FORWARD);
-      B.Add(newFace,wir);
-
-      BRepTopAdaptor_FClass2d FClass2d1(newFace,precuv);
-      TopAbs_State stat1 = FClass2d1.PerformInfinitePoint();
-      //di << "Wire " << i << ": Infinite point is " <<
-      //  ( stat1 == TopAbs_IN ? "IN" : stat1 == TopAbs_OUT ? "OUT" : stat1 == TopAbs_ON ? "ON" : "UNKNOWN" ) << "\n";
-
-      TCollection_AsciiString TmpString;
-      stat1 == TopAbs_IN ? TmpString.AssignCat("IN") : stat1 == TopAbs_OUT ? TmpString.AssignCat("OUT") : stat1 == TopAbs_ON ? TmpString.AssignCat("ON") : TmpString.AssignCat("UNKNOWN");
-      di << "Wire " << i << ": Infinite point is " << TmpString.ToCString() << "\n";
-
-      stat1 = FClass2d1.Perform(p2d);
-      //di << "Wire " << i << ": point ( " << p2d.X() << ", " << p2d.Y() << " ) is " <<
-      //  ( stat1 == TopAbs_IN ? "IN" : stat1 == TopAbs_OUT ? "OUT" : stat1 == TopAbs_ON ? "ON" : "UNKNOWN" ) << "\n";
-
-      TmpString.Clear();
-      stat1 == TopAbs_IN ? TmpString.AssignCat("IN") : stat1 == TopAbs_OUT ? TmpString.AssignCat("OUT") : stat1 == TopAbs_ON ? TmpString.AssignCat("ON") : TmpString.AssignCat("UNKNOWN");
-      di << "Wire " << i << ": point ( " << p2d.X() << ", " << p2d.Y() << " ) is " << TmpString.ToCString() << "\n";
-
-      // 4.2. Verify whether enrtry point is on reversed wire
-      newFace = TopoDS::Face(Shape.EmptyCopied());
-      newFace.Orientation(TopAbs_FORWARD);
-      orWire = TopAbs::Reverse(orWire);
-      B.Add(newFace,wir.Oriented(orWire));
-      BRepTopAdaptor_FClass2d FClass2d2(newFace,precuv);
-      TopAbs_State stat2 = FClass2d2.PerformInfinitePoint();
-      //di << "Reversed Wire " << i << ": Infinite point is " <<
-      //  ( stat2 == TopAbs_IN ? "IN" : stat2 == TopAbs_OUT ? "OUT" : stat2 == TopAbs_ON ? "ON" : "UNKNOWN" ) << "\n";
-
-      TmpString.Clear();
-      stat2 == TopAbs_IN ? TmpString.AssignCat("IN") : stat2 == TopAbs_OUT ? TmpString.AssignCat("OUT") : stat2 == TopAbs_ON ? TmpString.AssignCat("ON") : TmpString.AssignCat("UNKNOWN");
-      di << "Reversed Wire " << i << ": Infinite point is " << TmpString.ToCString() << "\n";
-
-      stat2 = FClass2d2.Perform(p2d);
-      //di << "Reversed Wire " << i << ": point ( " << p2d.X() << ", " << p2d.Y() << " ) is " <<
-      //  ( stat2 == TopAbs_IN ? "IN" : stat2 == TopAbs_OUT ? "OUT" : stat2 == TopAbs_ON ? "ON" : "UNKNOWN" ) << "\n";
-
-      TmpString.Clear();
-      stat2 == TopAbs_IN ? TmpString.AssignCat("IN") : stat2 == TopAbs_OUT ? TmpString.AssignCat("OUT") : stat2 == TopAbs_ON ? TmpString.AssignCat("ON") : TmpString.AssignCat("UNKNOWN");
-      di << "Reversed Wire " << i << ": point ( " << p2d.X() << ", " << p2d.Y() << " ) is " << TmpString.ToCString() << "\n";
-
-      // 4.3. Compare results (they must be same)
-      if(stat1 ==stat2) di << "OCC377 OK\n";
-      else {di << "OCC377 FAULTY\n"; return 0;}
-    }
-  }
-  catch(Standard_Failure)
-  {
-    di << "OCC377 Exception";
-  }
-
-  return 0;
-}
-
 #include <ShapeUpgrade_ShapeDivideAngle.hxx>
 #include <ShapeBuild_ReShape.hxx>
 
@@ -4838,7 +4748,6 @@ void QABugs::Commands_11(Draw_Interpretor& theCommands) {
   theCommands.Add("OCC363", "OCC363 document filename ", __FILE__, OCC363, group);
   // Must use OCC299
   //theCommands.Add("OCC372", "OCC372", __FILE__, OCC372, group);
-  theCommands.Add("OCC377", "OCC377", __FILE__, OCC377, group);
   theCommands.Add("OCC22", "OCC22 Result Shape CompoundOfSubshapesToBeDivided ConsiderLocation", __FILE__, OCC22, group);
   theCommands.Add("OCC24", "OCC24 Result Shape CompoundOfSubshapes ResourceFileName", __FILE__, OCC24, group);
   theCommands.Add("OCC369", "OCC369 Shape", __FILE__, OCC369, group);
diff --git a/src/QABugs/QABugs_8.cxx b/src/QABugs/QABugs_8.cxx
index 075003b..13c61df 100644
--- a/src/QABugs/QABugs_8.cxx
+++ b/src/QABugs/QABugs_8.cxx
@@ -142,7 +142,7 @@ static Standard_Integer OCC1651 (Draw_Interpretor& di, Standard_Integer argc, co
   gp_Dir aD1(Draw::Atof(argv[5]), Draw::Atof(argv[6]), Draw::Atof(argv[7]));
   gp_Lin aL1(aP1,aD1);
   BRepClass3d_Intersector3d aI1;
-  aI1.Perform(aL1, -250, 1e-7, TopoDS::Face(aShape));
+  aI1.Perform(aL1, 1e-7, TopoDS::Face(aShape));
   if(aI1.IsDone() && aI1.HasAPoint()) {
     gp_Pnt aR1 = aI1.Pnt();
     di << aR1.X() << " " << aR1.Y() << " " << aR1.Z() << "\n";
diff --git a/src/RWStepVisual/RWStepVisual_RWPresentationLayerAssignment.cxx b/src/RWStepVisual/RWStepVisual_RWPresentationLayerAssignment.cxx
index 2cf4d65..736764f 100644
--- a/src/RWStepVisual/RWStepVisual_RWPresentationLayerAssignment.cxx
+++ b/src/RWStepVisual/RWStepVisual_RWPresentationLayerAssignment.cxx
@@ -54,7 +54,7 @@ void RWStepVisual_RWPresentationLayerAssignment::ReadStep
 	Standard_Integer nsub3;
 	if (data->ReadSubList (num,3,"assigned_items",ach,nsub3)) {
 	  Standard_Integer nb3 = data->NbParams(nsub3);
-	  aAssignedItems = new StepVisual_HArray1OfLayeredItem (1, nb3);
+	  aAssignedItems = new StepVisual_HArray1OfLayeredItem (1, Max(nb3, 1));
 	  for (Standard_Integer i3 = 1; i3 <= nb3; i3 ++) {
 	    //szv#4:S4163:12Mar99 `Standard_Boolean stat3 =` not needed
 	    if (data->ReadEntity (nsub3,i3,"assigned_items",ach,aAssignedItemsItem))
diff --git a/src/SWDRAW/SWDRAW_ShapeAnalysis.cxx b/src/SWDRAW/SWDRAW_ShapeAnalysis.cxx
index 53452db..078cee6 100644
--- a/src/SWDRAW/SWDRAW_ShapeAnalysis.cxx
+++ b/src/SWDRAW/SWDRAW_ShapeAnalysis.cxx
@@ -18,6 +18,7 @@
 
 #include <BRep_Builder.hxx>
 #include <BRep_Tool.hxx>
+#include <BRepAdaptor_Surface.hxx>
 #include <BRepBuilderAPI.hxx>
 #include <BRepBuilderAPI_MakeFace.hxx>
 #include <BRepGProp.hxx>
@@ -316,6 +317,8 @@ static Standard_Integer anaface
     di<<"\n";
   }
   else { di<<"Analyse Wires, Ignore Faces\n"; }
+
+  const Standard_Real aTolF = BRep_Tool::Tolerance(Face);
   Standard_Boolean iasurf = !surface.IsNull();
 //:sw  if (!Face.IsNull()) STW.SetFace (Face);
 //:sw  else STW.SetPrecision (BRepBuilderAPI::Precision());
@@ -432,7 +435,7 @@ static Standard_Integer anaface
       if (G.Mass() > 0) di<<"GProps:Mass Out\n";
       else di<<"GProps:Mass In\n";
 ///  return (G.Mass() > 0);
-      BRepTopAdaptor_FClass2d fcl (Face,BRep_Tool::Tolerance(Face));
+      BRepTopAdaptor_FClass2d fcl(Face, aTolF);
       if (fcl.PerformInfinitePoint () == TopAbs_OUT) di<<"Classifier Infinite : Out\n";
       else di<<"Classifier Infinite : In\n";
       gp_Pnt2d pcl;
diff --git a/src/ShapeAnalysis/ShapeAnalysis.cxx b/src/ShapeAnalysis/ShapeAnalysis.cxx
index fdc65a7..a4bef1e 100644
--- a/src/ShapeAnalysis/ShapeAnalysis.cxx
+++ b/src/ShapeAnalysis/ShapeAnalysis.cxx
@@ -230,10 +230,8 @@ Standard_Boolean ShapeAnalysis::IsOuterBound(const TopoDS_Face& face)
     return (totcross >= 0);
   }
   else {
-    BRepAdaptor_Surface Ads ( F, Standard_False ); 
-    Standard_Real tol = BRep_Tool::Tolerance(F);
-    Standard_Real toluv = Min ( Ads.UResolution(tol), Ads.VResolution(tol) );
-    BRepTopAdaptor_FClass2d fcl (F,toluv);
+    const Standard_Real aTol = BRep_Tool::Tolerance(F);
+    BRepTopAdaptor_FClass2d fcl(F, aTol);
     Standard_Boolean rescl = (fcl.PerformInfinitePoint () == TopAbs_OUT);
     return rescl;
   }
diff --git a/src/ShapeFix/ShapeFix_ComposeShell.cxx b/src/ShapeFix/ShapeFix_ComposeShell.cxx
index 9afe4ff..e322048 100644
--- a/src/ShapeFix/ShapeFix_ComposeShell.cxx
+++ b/src/ShapeFix/ShapeFix_ComposeShell.cxx
@@ -2433,7 +2433,7 @@ void ShapeFix_ComposeShell::MakeFacesOnPatch (TopTools_SequenceOfShape &faces,
       TopoDS_Face fc;
       B.MakeFace ( fc, surf, myLoc, ::Precision::Confusion() );
       B.Add ( fc, awtmp );
-      BRepTopAdaptor_FClass2d clas ( fc, ::Precision::PConfusion() );
+      BRepTopAdaptor_FClass2d clas ( fc, Precision::Confusion() );
       TopAbs_State stPoint = clas.Perform (unp,Standard_False);
       if(stPoint == TopAbs_ON || stPoint == TopAbs_UNKNOWN) {
 
@@ -2486,7 +2486,7 @@ void ShapeFix_ComposeShell::MakeFacesOnPatch (TopTools_SequenceOfShape &faces,
     TopoDS_Face fc;
     B.MakeFace ( fc, surf, myLoc, ::Precision::Confusion() );
     B.Add ( fc, wire );
-    BRepTopAdaptor_FClass2d clas ( fc, ::Precision::PConfusion() );
+    BRepTopAdaptor_FClass2d clas ( fc, Precision::Confusion() );
     if ( clas.PerformInfinitePoint() == TopAbs_IN ) {
       reverse = Standard_True;
 #ifdef OCCT_DEBUG
diff --git a/src/ShapeFix/ShapeFix_Face.cxx b/src/ShapeFix/ShapeFix_Face.cxx
index 9ebadf5..31020de 100644
--- a/src/ShapeFix/ShapeFix_Face.cxx
+++ b/src/ShapeFix/ShapeFix_Face.cxx
@@ -1195,12 +1195,8 @@ Standard_Boolean ShapeFix_Face::FixOrientation(TopTools_DataMapOfShapeListOfShap
 //      B.MakeFace (af,mySurf->Surface(),::Precision::Confusion());
       af.Orientation ( TopAbs_FORWARD );
       B.Add (af,aw);
-      // PTV OCC945 06.11.2002 files ie_exhaust-A.stp (entities 3782,  3787)
-      // tolerance is too big. It is seems that to identify placement of 2d point
-      // it is enough Precision::PConfusion(), cause wea re know that 2d point in TopAbs_ON
-      // BRepTopAdaptor_FClass2d clas (af,toluv);
       Standard_Boolean CheckShift = Standard_True;
-      BRepTopAdaptor_FClass2d clas (af,::Precision::PConfusion());
+      BRepTopAdaptor_FClass2d clas (af, 0.0);
       TopAbs_State sta = TopAbs_OUT;
       TopAbs_State staout = clas.PerformInfinitePoint();
       TopTools_ListOfShape IntWires;
@@ -2438,7 +2434,7 @@ Standard_Boolean ShapeFix_Face::FixSplitFace(const TopTools_DataMapOfShapeListOf
         TopoDS_Face aFace = TopoDS::Face ( aShapeEmptyCopied);
         aFace.Orientation ( TopAbs_FORWARD );
         B.Add (aFace,liter.Value());
-        BRepTopAdaptor_FClass2d clas (aFace,::Precision::PConfusion());
+        BRepTopAdaptor_FClass2d clas (aFace, 0.0);
         TopAbs_State staout = clas.PerformInfinitePoint();
         if (staout == TopAbs_IN) 
           B.Add(tmpFace,liter.Value());
diff --git a/src/TNaming/TNaming.cxx b/src/TNaming/TNaming.cxx
index d4a0bc1..5d5fd4a 100644
--- a/src/TNaming/TNaming.cxx
+++ b/src/TNaming/TNaming.cxx
@@ -17,10 +17,11 @@
 
 #include <BRep_Builder.hxx>
 #include <BRep_Tool.hxx>
+#include <BRepAdaptor_Surface.hxx>
 #include <BRepBuilderAPI_Transform.hxx>
 #include <BRepClass3d_SolidClassifier.hxx>
+#include <BRepTopAdaptor_FClass2d.hxx>
 #include <gp_Trsf.hxx>
-#include <IntTools_FClass2d.hxx>
 #include <TColStd_IndexedDataMapOfTransientTransient.hxx>
 #include <TDF_ChildIterator.hxx>
 #include <TDF_Label.hxx>
@@ -917,16 +918,17 @@ Standard_Boolean TNaming::OuterWire(const TopoDS_Face& theFace, TopoDS_Wire& the
   TopoDS_Face aFx;
   TopoDS_Wire aWx;
   BRep_Builder aBB;
-  IntTools_FClass2d aFC;
+  BRepTopAdaptor_FClass2d aFC;
   Standard_Boolean bFlag(Standard_False);
-  Standard_Real aTol = BRep_Tool::Tolerance(theFace);
+  Standard_Real aTolF = BRep_Tool::Tolerance(theFace);
+
   TopoDS_Iterator aIt(theFace);
   for (; aIt.More(); aIt.Next()) {
     aWx=*((TopoDS_Wire*)&aIt.Value());
     aFx = theFace;
     aFx.EmptyCopy();
     aBB.Add(aFx, aWx);
-    aFC.Init(aFx, aTol);
+    aFC.Init(aFx, aTolF);
     bFlag = aFC.IsHole();
     if (!bFlag) 
       break;
diff --git a/src/TopClass/FILES b/src/TopClass/FILES
index b6b1e48..527e043 100755
--- a/src/TopClass/FILES
+++ b/src/TopClass/FILES
@@ -4,7 +4,11 @@ TopClass_Classifier2d.lxx
 TopClass_Classifier3d.gxx
 TopClass_Classifier3d.lxx
 TopClass_FaceClassifier.gxx
-TopClass_FaceClassifier.lxx
+TopClass_GeomEdge.cxx
+TopClass_GeomEdge.hxx
+TopClass_GeomVertex.cxx
+TopClass_GeomVertex.hxx
+TopClass_RayInfo.hxx
 TopClass_SolidClassifier.gxx
 TopClass_SolidExplorer.cxx
 TopClass_SolidExplorer.hxx
diff --git a/src/TopClass/TopClass_Classifier2d.gxx b/src/TopClass/TopClass_Classifier2d.gxx
index 22f46b3..f690452 100644
--- a/src/TopClass/TopClass_Classifier2d.gxx
+++ b/src/TopClass/TopClass_Classifier2d.gxx
@@ -19,10 +19,8 @@
 
 //  Modified by skv - Wed Jul 12 15:20:58 2006 OCC12627
 
-
-#include <IntRes2d_IntersectionSegment.hxx>
-#include <IntRes2d_IntersectionPoint.hxx>
-#include <gp_Vec2d.hxx>
+#include <GeomLib.hxx>
+#include <TopClass_GeomEdge.hxx>
 
 //=======================================================================
 //function : TopClass_Classifier2d
@@ -30,7 +28,6 @@
 //=======================================================================
 
 TopClass_Classifier2d::TopClass_Classifier2d() :
-       myIsSet(Standard_False),
        myFirstCompare(Standard_True),
        myState(TopAbs_UNKNOWN),      // skv OCC12627
        myIsHeadOrEnd(Standard_False) // skv OCC12627
@@ -42,18 +39,15 @@ TopClass_Classifier2d::TopClass_Classifier2d() :
 //purpose  : 
 //=======================================================================
 
-void TopClass_Classifier2d::Reset(const gp_Lin2d& L,  
-				  const Standard_Real P,
-				  const Standard_Real Tol)
+void TopClass_Classifier2d::Reset(const gp_Lin2d& L,
+                                  const Standard_Real P)
 {
   myLin = L;
   myParam = P;
-  myTolerance = Tol;
   myState = TopAbs_UNKNOWN;
   myFirstCompare = Standard_True;
   myFirstTrans = Standard_True;
   myClosest = 0;
-  myIsSet = Standard_True;
 //  Modified by skv - Wed Jul 12 15:20:58 2006 OCC12627 Begin
   myIsHeadOrEnd = Standard_False;
 //  Modified by skv - Wed Jul 12 15:20:58 2006 OCC12627 End
@@ -64,12 +58,17 @@ void TopClass_Classifier2d::Reset(const gp_Lin2d& L,
 //purpose  : 
 //=======================================================================
 
-void TopClass_Classifier2d::Compare(const TheEdge& E,
-				    const TopAbs_Orientation Or)
+void TopClass_Classifier2d::Compare(const TopClass_GeomEdge& theE,
+                                    const Standard_Real theTol2D)
 {
+  // if the Edge is INTERNAL or EXTERNAL, no problem
+  if ((theE.GetOrientation() != TopAbs_FORWARD) && 
+      (theE.GetOrientation() != TopAbs_REVERSED))
+    return;
+
   // intersect the edge and the segment
   myClosest = 0;
-  myIntersector.Perform(myLin,myParam,myTolerance,E);
+  myIntersector.Perform(myLin, myParam, theTol2D, theE);
   if (!myIntersector.IsDone()) return;
   if ((myIntersector.NbPoints()   == 0)&&
       (myIntersector.NbSegments() == 0)) return;
@@ -119,17 +118,6 @@ void TopClass_Classifier2d::Compare(const TheEdge& E,
   // if no point was found return
   if (myClosest == 0) return;
 
-  // if the Edge is INTERNAL or EXTERNAL, no problem
-  if (Or == TopAbs_INTERNAL) {
-    myState = TopAbs_IN;
-    return;
-  }
-  else if (Or == TopAbs_EXTERNAL) {
-    myState = TopAbs_OUT;
-    return;
-  }
-
-
   if ( ! myFirstCompare ) {
     Standard_Boolean b = (dMin > myParam);
     if (b) {
@@ -161,29 +149,38 @@ void TopClass_Classifier2d::Compare(const TheEdge& E,
   TopAbs_Orientation SegTrans = TopAbs_FORWARD;
 
   const IntRes2d_Transition& T1 = PClosest->TransitionOfFirst();
-  switch (T1.TransitionType()) {
-  case IntRes2d_In :
-    if (Or == TopAbs_REVERSED)   SegTrans = TopAbs_REVERSED;
-    else                         SegTrans = TopAbs_FORWARD;
+  switch (T1.TransitionType())
+  {
+  case IntRes2d_In:
+    SegTrans = theE.GetOrientation();
     break;
-  case IntRes2d_Out :
-    if (Or == TopAbs_REVERSED)   SegTrans = TopAbs_FORWARD;
-    else                         SegTrans = TopAbs_REVERSED;
+  case IntRes2d_Out:
+    if (theE.GetOrientation() == TopAbs_REVERSED)
+      SegTrans = TopAbs_FORWARD;
+    else
+      SegTrans = TopAbs_REVERSED;
     break;
-  case IntRes2d_Touch :
-    switch (T1.Situation()) {
-    case IntRes2d_Inside :
-      if (Or == TopAbs_REVERSED) SegTrans = TopAbs_EXTERNAL;
-      else                       SegTrans = TopAbs_INTERNAL;
+  case IntRes2d_Touch:
+    switch (T1.Situation())
+    {
+    case IntRes2d_Inside:
+      if (theE.GetOrientation() == TopAbs_REVERSED)
+        SegTrans = TopAbs_EXTERNAL;
+      else
+        SegTrans = TopAbs_INTERNAL;
       break;
-    case IntRes2d_Outside :
-      if (Or == TopAbs_REVERSED) SegTrans = TopAbs_INTERNAL;
-      else                       SegTrans = TopAbs_EXTERNAL;
+    case IntRes2d_Outside:
+      if (theE.GetOrientation() == TopAbs_REVERSED)
+        SegTrans = TopAbs_INTERNAL;
+      else
+        SegTrans = TopAbs_EXTERNAL;
       break;
-    case IntRes2d_Unknown :      return;
+    case IntRes2d_Unknown:
+      return;
     }
     break;
-  case IntRes2d_Undecided :      return;
+  case IntRes2d_Undecided:
+    return;
   }
 
   // are we inside the Edge ?
@@ -207,8 +204,13 @@ void TopClass_Classifier2d::Compare(const TheEdge& E,
     // PClosest is Head or End of the edge : update the complex transition
     gp_Dir2d Tang2d,Norm2d;
     Standard_Real Curv;
-    myIntersector.LocalGeometry
-      (E,PClosest->ParamOnSecond(),Tang2d,Norm2d,Curv);
+    if(!GeomLib::LocalGeometry(theE.Get2DCurve().Curve(),
+                               PClosest->ParamOnSecond(),
+                               Tang2d, Norm2d, Curv))
+    {
+      return;
+    }
+
     gp_Dir Tang(Tang2d.X(),Tang2d.Y(),0.);
     gp_Dir Norm(Norm2d.X(),Norm2d.Y(),0.);
     if (myFirstTrans) {
diff --git a/src/TopClass/TopClass_Classifier3d.gxx b/src/TopClass/TopClass_Classifier3d.gxx
index a5a77b0..8eef1d2 100644
--- a/src/TopClass/TopClass_Classifier3d.gxx
+++ b/src/TopClass/TopClass_Classifier3d.gxx
@@ -43,7 +43,7 @@ void TopClass_Classifier3d::Compare(const TopoDS_Face&        Face,
   }
 
   hasIntersect = Standard_False;
-  myIntersector.Perform(myLin,myParam,myTolerance,Face);
+  myIntersector.Perform(myLin,myTolerance,Face);
   if(myIntersector.IsDone()) { 
     if(myIntersector.HasAPoint()) { 
       hasIntersect = Standard_True;
diff --git a/src/TopClass/TopClass_FaceClassifier.gxx b/src/TopClass/TopClass_FaceClassifier.gxx
index 7f86749..ee76a4c 100644
--- a/src/TopClass/TopClass_FaceClassifier.gxx
+++ b/src/TopClass/TopClass_FaceClassifier.gxx
@@ -17,138 +17,192 @@
 //  Modified by skv - Thu Jul 13 18:00:34 2006 OCC12627
 // The method Perform is totally rewroted.
 
-#include <IntRes2d_IntersectionSegment.hxx>
-#include <IntRes2d_IntersectionPoint.hxx>
+#include <algorithm>
 
-//=======================================================================
-//function : TopClass_FaceClassifier
-//purpose  : 
-//=======================================================================
-
-TopClass_FaceClassifier::TopClass_FaceClassifier() :
-myEdgeParameter(0.0),
-rejected(Standard_False),
-nowires(Standard_True)
-{
-}
+#include <BRep_Tool.hxx>
+#include <NCollection_Array1.hxx>
+#include <TopClass_RayInfo.hxx>
 
 //=======================================================================
 //function : TopClass_FaceClassifier
 //purpose  : 
 //=======================================================================
-
-TopClass_FaceClassifier::TopClass_FaceClassifier(TheFaceExplorer& FExp,
-						 const gp_Pnt2d& P,
-						 const Standard_Real Tol) :
+TopClass_FaceClassifier::TopClass_FaceClassifier() :
 myEdgeParameter(0.0),
-rejected(Standard_False),
-nowires(Standard_True)
+myState(TopAbs_UNKNOWN)
 {
-  Perform(FExp,P,Tol);
 }
 
 //=======================================================================
 //function : Perform
 //purpose  : 
 //=======================================================================
-
-void TopClass_FaceClassifier::Perform(TheFaceExplorer& Fexp,
-				      const gp_Pnt2d& P,
-				      const Standard_Real Tol)
+void TopClass_FaceClassifier::Perform(TheFaceExplorer& theFExp,
+                                      const gp_Pnt2d& theP,
+                                      const Standard_Real theTol2D)
 {
-  gp_Pnt2d aPoint(P);
+  myEdge = TopClass_GeomEdge();
+  myEdgeParameter = 0.0;
+  myState = TopAbs_UNKNOWN;
+
+  gp_Pnt2d aPoint(theP);
   Standard_Boolean aResOfPointCheck = Standard_False;
   while (aResOfPointCheck == Standard_False)
   {
-    aResOfPointCheck = Fexp.CheckPoint(aPoint);
+    aResOfPointCheck = theFExp.CheckPoint(aPoint);
   }
 
-  // Test for rejection.
-  rejected = Fexp.Reject(aPoint);
-
-  if (rejected)
-    return;
+  TopClass_GeomEdge          anEdge;
 
-  gp_Lin2d                   aLine;
-  Standard_Real              aParam;
-  Standard_Boolean           IsValidSegment = Fexp.Segment(aPoint, aLine, aParam);
-  TheEdge                    anEdge;
-  TopAbs_Orientation         anEdgeOri;
   Standard_Integer           aClosestInd;
   IntRes2d_IntersectionPoint aPInter;
-  TopAbs_State               aState = TopAbs_UNKNOWN;
-  Standard_Boolean           IsWReject;
-  Standard_Boolean           IsEReject;
-
-  nowires = Standard_True;
-
-  while (IsValidSegment) {
-    myClassifier.Reset(aLine, aParam, Tol);
-
-    for (Fexp.InitWires(); Fexp.MoreWires(); Fexp.NextWire()) {
-      nowires   = Standard_False;
-      IsWReject = Fexp.RejectWire(aLine, myClassifier.Parameter());
-
-      if (!IsWReject) {
-	// test this wire
-	for (Fexp.InitEdges(); Fexp.MoreEdges(); Fexp.NextEdge()) {
-	  IsEReject = Fexp.RejectEdge(aLine, myClassifier.Parameter());
-
-	  if (!IsEReject) {
-	    // test this edge
-	    Fexp.CurrentEdge(anEdge, anEdgeOri);
-
-	    if (anEdgeOri == TopAbs_FORWARD || anEdgeOri == TopAbs_REVERSED) {
-	      myClassifier.Compare(anEdge, anEdgeOri);
-	      aClosestInd = myClassifier.ClosestIntersection();
-
-	      if (aClosestInd != 0) {
-		// save the closest edge
-		TheIntersection2d &anIntersector = myClassifier.Intersector();
-		Standard_Integer   aNbPnts       = anIntersector.NbPoints();
-
-		myEdge = anEdge;
-
-		if (aClosestInd <= aNbPnts) {
-		  aPInter = anIntersector.Point(aClosestInd);
-		} else {
-		  aClosestInd -= aNbPnts;
-
-		  if (aClosestInd&1) {
-		    aPInter =  anIntersector.
-		      Segment((aClosestInd + 1)/2).FirstPoint();
-		  } else {
-		    aPInter =  anIntersector.
-		      Segment((aClosestInd + 1)/2).LastPoint();
-		  }
-		}
-
-		myPosition      = aPInter.
-		                  TransitionOfSecond().PositionOnCurve();
-		myEdgeParameter = aPInter.ParamOnSecond();
-	      }
-	      // if we are ON, we stop
-	      aState = myClassifier.State();
-	    
-	      if (aState == TopAbs_ON)
-		return;
-	    }
-	  }
-	}
-
-	// if we are out of the wire we stop
-	aState = myClassifier.State();
-
-	if (aState == TopAbs_OUT)
-	  return;
+  TopClass_FClass2d aClassifier;
+
+  //These two constants are entered in order to speeding up the performance.
+  unsigned int aMaxWeight = UINT_MAX;
+  const Standard_Real aMaxDelta = 0.01;
+
+  Standard_Boolean hasWires = Standard_False;
+  TopClass_RayInfo aRayInfo;
+
+  theFExp.FirstRay(aPoint, aRayInfo);
+  Standard_Real aRealInterval = aRayInfo.MinDeltaInterval();
+
+  do
+  {
+    aClassifier.Reset(aRayInfo.GetLine(), aRayInfo.GetParameter());
+
+    for (theFExp.InitWires(); theFExp.MoreWires(); theFExp.NextWire())
+    {
+      // Counts penalties added by TheFaceExplorer::IsPointInEdgeVertex(...) method
+      unsigned int aSumPenaltyVertCoinc = 0;
+
+      // test this wire
+      for (theFExp.InitEdges(); theFExp.MoreEdges(); theFExp.NextEdge())
+      {
+        // Empty face is possible:
+        //    plane pl 0 0 0 0 0 1
+        //    mkface ff pl
+        // As result, ff does not contain any wires/edges/vertices.
+        // However, Geom2dHatch_Classifier (which is used by DBRep_IsoBuilder)
+        // returns some wire but does not find any edge. Therefore, "hasWires"
+        // flag should be put to the current "edges"-cycle (not outer "wires"-cycle).
+        hasWires = Standard_True;
+        
+        // test this edge
+        theFExp.CurrentEdge(anEdge);
+        if ((anEdge.GetOrientation() != TopAbs_FORWARD) &&
+            (anEdge.GetOrientation() != TopAbs_REVERSED))
+        {
+          continue;
+        }
+
+        //Intersects with anEdge
+        aClassifier.Compare(anEdge, theTol2D);
+        aClosestInd = aClassifier.ClosestIntersection();
+
+        if (aClosestInd != 0)
+        {
+          // save the closest edge
+          TheIntersection2d &anIntersector = aClassifier.Intersector();
+          Standard_Integer  aNbPnts = anIntersector.NbPoints();
+
+          myEdge = anEdge;
+
+          if (aClosestInd <= aNbPnts)
+          {
+            aPInter = anIntersector.Point(aClosestInd);
+          }
+          else
+          {
+            aClosestInd -= aNbPnts;
+
+            //Tangential case
+            aRayInfo.AddPenalty(2);
+
+            if (aClosestInd & 1) {
+              aPInter = anIntersector.
+                Segment((aClosestInd + 1) / 2).FirstPoint();
+            }
+            else
+            {
+              aPInter = anIntersector.
+                Segment((aClosestInd + 1) / 2).LastPoint();
+            }
+          }
+
+          const gp_Pnt2d &aPOnC = aPInter.Value();
+          if (theFExp.IsPointInEdgeVertex(aPOnC))
+          {
+            const unsigned int aPenaltyVal = 5u;
+            aSumPenaltyVertCoinc += aPenaltyVal;
+            aRayInfo.AddPenalty(aPenaltyVal);
+          }
+
+          aRayInfo.AddParamOnLine(aPInter.ParamOnFirst());
+
+          myEdgeParameter = aPInter.ParamOnSecond();
+        }
+        
+        if ((aClassifier.State() == TopAbs_ON) &&
+            (aRayInfo.GetWeight() == aSumPenaltyVertCoinc))
+        {
+          // if we are ON, we stop. In case only if we can trust this info.
+          // In case of ON-status we can trust the ray going through the edge vertex.
+          myState = TopAbs_ON;
+          return;
+        }
+      }
+
+      if (aRayInfo.MinDeltaInterval() < aMaxDelta)
+      {
+        aRayInfo.AddPenalty();
+      }
+
+      aRayInfo.SetState(aClassifier.State());
+
+      if ((aRayInfo.GetState() == TopAbs_OUT) && (aRayInfo.GetWeight() == 0))
+      {
+        // If we are out of the wire we stop. In case only if we can trust this info.
+        myState = TopAbs_OUT;
+        return;
       }
     }
 
-    if (!myClassifier.IsHeadOrEnd() && aState != TopAbs_UNKNOWN)
-      break;
+    if ((aClassifier.State() != TopAbs_UNKNOWN) && ((myState == TopAbs_UNKNOWN) ||
+                                                    (aRayInfo.GetWeight() <= aMaxWeight)))
+    {
+      if (aRayInfo.GetWeight() < aMaxWeight)
+      {
+        aMaxWeight = aRayInfo.GetWeight();
+        aRealInterval = aRayInfo.MinDeltaInterval();
+        myState = aClassifier.State();
+      }
+      else if (aRayInfo.MinDeltaInterval() >= aRealInterval)
+      {
+        myState = aClassifier.State();
+        aRealInterval = aRayInfo.MinDeltaInterval();
+      }
+      else if (myState == TopAbs_UNKNOWN)
+      {
+        myState = aClassifier.State();
+      }
+      
+      if (!aClassifier.IsHeadOrEnd() && (aRayInfo.GetWeight() == 0))
+      {
+        myState = aClassifier.State();
+        return;
+      }
+    }
+  }
+  while (hasWires && 
+         ((aRayInfo.GetWeight() != 0) || (myState == TopAbs_UNKNOWN)) &&
+         theFExp.OtherRay(aPoint, aRayInfo, aMaxWeight));
 
-    // Bad case for classification. Trying to get another segment.
-    IsValidSegment = Fexp.OtherSegment(aPoint, aLine, aParam);
+  if (!hasWires)
+  {
+    myState = TopAbs_IN;
+    return;
   }
 }
 
@@ -159,33 +213,6 @@ void TopClass_FaceClassifier::Perform(TheFaceExplorer& Fexp,
 
 TopAbs_State TopClass_FaceClassifier::State() const
 {
-  if (rejected)     return TopAbs_OUT;
-  else if (nowires) return TopAbs_IN;
-  else              return  myClassifier.State();
-}
-
-//=======================================================================
-//function : Edge
-//purpose  : 
-//=======================================================================
-
-const TheEdge& TopClass_FaceClassifier::Edge() const
-{
-  Standard_DomainError_Raise_if(rejected,
-				"TopClass_FaceClassifier::Edge:rejected");
-  return myEdge;
-}
-
-
-//=======================================================================
-//function : EdgeParameter
-//purpose  : 
-//=======================================================================
-
-Standard_Real TopClass_FaceClassifier::EdgeParameter() const
-{
-  Standard_DomainError_Raise_if(rejected,
-				"TopClass_FaceClassifier::EdgeParameter:rejected");
-  return myEdgeParameter;
+  return myState;
 }
 
diff --git a/src/TopClass/TopClass_FaceClassifier.lxx b/src/TopClass/TopClass_FaceClassifier.lxx
deleted file mode 100644
index abafb35..0000000
--- a/src/TopClass/TopClass_FaceClassifier.lxx
+++ /dev/null
@@ -1,48 +0,0 @@
-// Created on: 1992-11-18
-// Created by: Remi LEQUETTE
-// Copyright (c) 1992-1999 Matra Datavision
-// Copyright (c) 1999-2014 OPEN CASCADE SAS
-//
-// This file is part of Open CASCADE Technology software library.
-//
-// This library is free software; you can redistribute it and/or modify it under
-// the terms of the GNU Lesser General Public License version 2.1 as published
-// by the Free Software Foundation, with special exception defined in the file
-// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
-// distribution for complete text of the license and disclaimer of any warranty.
-//
-// Alternatively, this file may be used under the terms of Open CASCADE
-// commercial license or contractual agreement.
-
-#include TheFaceExplorer_hxx
-
-//=======================================================================
-//function : Rejected
-//purpose  : 
-//=======================================================================
-
-inline Standard_Boolean TopClass_FaceClassifier::Rejected() const
-{
-  return rejected;
-}
-
-//=======================================================================
-//function : Nowires
-//purpose  : 
-//=======================================================================
-
-inline Standard_Boolean TopClass_FaceClassifier::NoWires() const
-{
-  return nowires;
-}
-
-//=======================================================================
-//function : Position
-//purpose  : 
-//=======================================================================
-
-inline IntRes2d_Position TopClass_FaceClassifier::Position() const
-{
-  return myPosition;
-}
-
diff --git a/src/TopClass/TopClass_GeomEdge.cxx b/src/TopClass/TopClass_GeomEdge.cxx
new file mode 100644
index 0000000..0dd2a7a
--- /dev/null
+++ b/src/TopClass/TopClass_GeomEdge.cxx
@@ -0,0 +1,247 @@
+// Created on: 2017-02-17
+// Created by: Nikolai BUKHALOV
+// Copyright (c) 1999-2017 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#include <TopClass_GeomEdge.hxx>
+
+#include <BRep_Tool.hxx>
+#include <Extrema_ExtPC.hxx>
+#include <Extrema_ExtPC2d.hxx>
+#include <TopExp.hxx>
+#include <TopExp_Explorer.hxx>
+#include <TopoDS.hxx>
+#include <TopoDS_Face.hxx>
+#include <TopoDS_Vertex.hxx>
+
+//=======================================================================
+//function : Constructor
+//purpose  : 
+//=======================================================================
+TopClass_GeomEdge::TopClass_GeomEdge(const Handle(Geom_Curve)& theC3D,
+                                     const Handle(Geom2d_Curve)& theC2D,
+                                     const Handle(Geom_Surface)& theS,
+                                     const Standard_Real theFPar,
+                                     const Standard_Real theLPar,
+                                     const TopAbs_Orientation theOri,
+                                     const TopClass_GeomVertex &theVf,
+                                     const TopClass_GeomVertex &theVl,
+                                     const Standard_Boolean theIsSameParameter)
+  : myOri(theOri),
+    myVertF(theVf),
+    myVertL(theVl),
+    myIsSameParameter(theIsSameParameter)
+{
+  Init(theC3D, theC2D, theS, theFPar, theLPar);
+}
+
+//=======================================================================
+//function : Constructor
+//purpose  : 
+//=======================================================================
+TopClass_GeomEdge::TopClass_GeomEdge(const TopoDS_Edge& theE,
+                                     const Handle(Geom_Surface)& theSurf,
+                                     const Handle(Geom2d_Curve)& theC2d,
+                                     const Standard_Real theFPar,
+                                     const Standard_Real theLPar)
+  : myTopoEdge(theE)
+{
+  myOri = theE.Orientation();
+  
+  if ((myOri != TopAbs_FORWARD) && (myOri != TopAbs_REVERSED))
+    return;
+
+  TopoDS_Vertex aVf, aVl;
+  TopExp::Vertices(theE, aVf, aVl, Standard_True);
+
+  myVertF.Init(aVf, theE);
+  myVertL.Init(aVl, theE);
+
+  Standard_Real aFPar = 1.0, aLPar = -1.0;
+  const Handle(Geom_Curve) aC3d = BRep_Tool::Curve(theE, aFPar, aLPar);
+
+  myIsSameParameter = (BRep_Tool::SameParameter(theE) && BRep_Tool::SameRange(theE));
+
+  Init(aC3d, theC2d, theSurf, theFPar, theLPar);
+}
+
+//=======================================================================
+//function : Init
+//purpose  : 
+//=======================================================================
+void TopClass_GeomEdge::Init(const Handle(Geom_Curve)& theC3D,
+                             const Handle(Geom2d_Curve)& theC2D,
+                             const Handle(Geom_Surface)& theS,
+                             const Standard_Real theFPar,
+                             const Standard_Real theLPar)
+{
+  if (theC2D.IsNull())
+    return;
+
+  myC2D.Load(theC2D, theFPar, theLPar);
+    
+  if (!theC3D.IsNull())
+    myC3D.Load(theC3D, theFPar, theLPar);
+  else
+    myIsSameParameter = Standard_False;
+
+  if (!theS.IsNull())
+    mySurf.Load(theS);
+  else
+    myIsSameParameter = Standard_False;
+}
+
+//=======================================================================
+//function : Distance3D
+//purpose  : 
+//=======================================================================
+Standard_Real TopClass_GeomEdge::Distance3D(const gp_Pnt &thePt,
+                                            gp_Pnt *thePOnC,
+                                            Standard_Real *theParOnC) const
+{
+  if (IsPseudo())
+  {
+    return -1.0;
+  }
+
+  // Default value for extrema algo.
+  const Standard_Real aTolPar = 1.0e-10;
+
+  Extrema_ExtPC anEG(thePt, myC3D, aTolPar);
+
+  if (!anEG.IsDone() || (anEG.NbExt() == 0))
+  {
+    const Standard_Real aDistF = thePt.SquareDistance(myVertF.GetPnt3D());
+    const Standard_Real aDistL = thePt.SquareDistance(myVertL.GetPnt3D());
+
+    if (aDistF < aDistL)
+    {
+      if (thePOnC)
+        thePOnC->SetXYZ(myVertF.GetPnt3D().XYZ());
+      if (theParOnC)
+        *theParOnC = myVertF.ParameterOnEdge();
+
+      return Sqrt(aDistF);
+    }
+    else // if (aDistL <= aDistF)
+    {
+      if (thePOnC)
+        thePOnC->SetXYZ(myVertL.GetPnt3D().XYZ());
+      if (theParOnC)
+        *theParOnC = myVertL.ParameterOnEdge();
+
+      return Sqrt(aDistL);
+    }
+  }
+
+  const Standard_Integer aNbExt = anEG.NbExt();
+  const Extrema_POnCurv *aNearPoint = 0;
+  Standard_Real aMinSqDist = RealLast();
+
+  for (Standard_Integer i = 1; i <= aNbExt; i++)
+  {
+    const Standard_Real aSqDist = anEG.SquareDistance(i);
+
+    if (aSqDist > aMinSqDist)
+      continue;
+
+    aMinSqDist = aSqDist;
+
+    const Extrema_POnCurv &aEPt = anEG.Point(i);
+    aNearPoint = &aEPt;
+  }
+
+  if (aNearPoint == 0)
+  {
+    return -1.0;
+  }
+
+  if (thePOnC)
+    thePOnC->SetXYZ(aNearPoint->Value().XYZ());
+  if (theParOnC)
+    *theParOnC = aNearPoint->Parameter();
+
+  return Sqrt(aMinSqDist);
+}
+
+//=======================================================================
+//function : Distance2D
+//purpose  : 
+//=======================================================================
+Standard_Real TopClass_GeomEdge::Distance2D(const gp_Pnt2d &thePt,
+                                            gp_Pnt2d *thePOnC,
+                                            Standard_Real *theParOnC) const
+{
+  // Default value for extrema algo.
+  const Standard_Real aTolPar = 1.0e-10;
+
+  Extrema_ExtPC2d anEG(thePt, myC2D, aTolPar);
+
+  if (!anEG.IsDone() || (anEG.NbExt() == 0))
+  {
+    const Standard_Real aParF = myC2D.FirstParameter();
+    const Standard_Real aParL = myC2D.LastParameter();
+
+    const gp_Pnt2d aPtF(myC2D.Value(aParF)), aPtL(myC2D.Value(aParL));
+    const Standard_Real aDistF = thePt.SquareDistance(aPtF);
+    const Standard_Real aDistL = thePt.SquareDistance(aPtL);
+
+    if (aDistF < aDistL)
+    {
+      if (thePOnC)
+        thePOnC->SetXY(aPtF.XY());
+      if (theParOnC)
+        *theParOnC = aParF;
+
+      return Sqrt(aDistF);
+    }
+    else // if (aDistL <= aDistF)
+    {
+      if (thePOnC)
+        thePOnC->SetXY(aPtL.XY());
+      if (theParOnC)
+        *theParOnC = aParL;
+
+      return Sqrt(aDistL);
+    }
+  }
+
+  const Standard_Integer aNbExt = anEG.NbExt();
+  const Extrema_POnCurv2d *aNearPoint = 0;
+  Standard_Real aMinSqDist = RealLast();
+
+  for (Standard_Integer i = 1; i <= aNbExt; i++)
+  {
+    const Standard_Real aSqDist = anEG.SquareDistance(i);
+
+    if (aSqDist > aMinSqDist)
+      continue;
+
+    aMinSqDist = aSqDist;
+
+    const Extrema_POnCurv2d &aEPt = anEG.Point(i);
+    aNearPoint = &aEPt;
+  }
+
+  if (aNearPoint == 0)
+  {
+    return -1.0;
+  }
+
+  if (thePOnC)
+    thePOnC->SetXY(aNearPoint->Value().XY());
+  if (theParOnC)
+    *theParOnC = aNearPoint->Parameter();
+
+  return Sqrt(aMinSqDist);
+}
diff --git a/src/TopClass/TopClass_GeomEdge.hxx b/src/TopClass/TopClass_GeomEdge.hxx
new file mode 100644
index 0000000..04300df
--- /dev/null
+++ b/src/TopClass/TopClass_GeomEdge.hxx
@@ -0,0 +1,230 @@
+// Created on: 2017-02-17
+// Created by: Nikolai BUKHALOV
+// Copyright (c) 1999-2017 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef _TopClass_GeomEdge_HeaderFile
+#define _TopClass_GeomEdge_HeaderFile
+
+#include <Standard_Type.hxx>
+
+#include <Geom2dAdaptor_Curve.hxx>
+#include <GeomAdaptor_Curve.hxx>
+#include <GeomAdaptor_Surface.hxx>
+#include <Precision.hxx>
+#include <TopClass_GeomVertex.hxx>
+#include <TopoDS_Edge.hxx>
+
+class Geom_Curve;
+class Geom_Surface;
+class Geom2d_Curve;
+class TopoDS_Face;
+
+//! Stores information about 3D-curve and
+//! correspond 2D-curve on the face for some edge
+//! (i.e. geometrical representation of the edge).
+//! This info is used for classifier algorithm only.
+//! 3D-curve can be Null-curve (for pseudo- or 
+//! degenerated-edge).
+//! Also, this class can store 2d-curve only (without 3D-curve
+//! and face). It makes this class compatible with
+//! Geom2dHatch_* classes.
+//! ATTENTIONS!!!
+//!   1. The information about 2D-curve has
+//! priority over the information about 3D one
+//! (e.g. First/Last-parameter are taken from 2D-curve).
+//!   2. This geometrical representation does not store any
+//! information about sharing of several edges. I.e. even if two
+//! edges are shared topologically, their geometrical representations
+//! will be two independent (to each other) edges. Every such edge will
+//! have two independent geometrical vertices (one vertex of
+//! 1st edge will be identical of the vertex of 2nd edge but
+//! these vertices will be different and independent to each other).
+
+class TopClass_GeomEdge
+{
+public:
+  //! Default constructor
+  Standard_EXPORT TopClass_GeomEdge() : myOri(TopAbs_EXTERNAL),
+                                        myIsSameParameter(Standard_False)
+  {};
+
+  //! Constructor. Creates edge, which is bounded by the vertices theVf theVl
+  //! and has orientation theOri. 3D- (theC3D) and 2D- (theC2D) curve on
+  //! the surface theS have range [theFirstParam, theLastParam].
+  //! theToler is 3D-tolerance of the edge (is used for check ON-status).
+  Standard_EXPORT TopClass_GeomEdge(const Handle(Geom_Curve)& theC3D,
+                                    const Handle(Geom2d_Curve)& theC2D,
+                                    const Handle(Geom_Surface)& theS,
+                                    const Standard_Real theFirstParam,
+                                    const Standard_Real theLastParam,
+                                    const TopAbs_Orientation theOri,
+                                    const TopClass_GeomVertex &theVf,
+                                    const TopClass_GeomVertex &theVl,
+                                    const Standard_Boolean theIsSameParameter);
+  
+  //! Constructor. Extracts necessary geometrical information from topological
+  //! edge theE lied in the face theF.
+  //! ATENTION!!!
+  //!   1. theE must have 2D-curve on theF. Otherwise, no object will be created.
+  //!   2. Orientation of *this (geometrical edge) will always match
+  //!     the orientation of theE. So, the application must set
+  //!     correct edge orientation before calling this constructor.
+  Standard_EXPORT TopClass_GeomEdge(const TopoDS_Edge& theE,
+                                    const Handle(Geom_Surface)& theSurf,
+                                    const Handle(Geom2d_Curve)& theC2d,
+                                    const Standard_Real theFPar,
+                                    const Standard_Real theLPar);
+
+  //! Replaces 2d-curve with theC.
+  void Replace2DCurve(const Geom2dAdaptor_Curve& theC,
+                      const TopAbs_Orientation theOri)
+  {
+    myC2D = theC;
+    myOri = theOri;
+  }
+
+  //! Looks for thePOnC, which is nearest point in
+  //! the 3D-curve myC3D to thePt. If (thePOnC != 0)
+  //! the found value will be assigned to thePOnC.
+  //! If (theParOnC != 0) the method will assign to it the
+  //! parameter on myC3D respected to thePOnC.
+  //! Returns the distance between thePt and thePOnC.
+  //! Returns negative value if computation is not possible.
+  Standard_EXPORT Standard_Real Distance3D(const gp_Pnt &thePt,
+                                           gp_Pnt *thePOnC = 0,
+                                           Standard_Real *theParOnC = 0) const;
+ 
+
+  //! Looks for thePOnC, which is nearest point in
+  //! the 2D-curve myC2D to thePt. If thePOnC != 0
+  //! the found value will be assigned to thePOnC.
+  //! If (theParOnC != 0) the method will assign to it the
+  //! parameter on myC2D respected to thePOnC.
+  //! Returns the distance between thePt and thePOnC.
+  //! Returns negative value if computation is not possible.
+  Standard_EXPORT Standard_Real Distance2D(const gp_Pnt2d &thePt,
+                                           gp_Pnt2d *thePOnC = 0,
+                                           Standard_Real *theParOnC = 0) const;
+
+  //! Returns 3D-curve of the edge
+  const GeomAdaptor_Curve& Get3DCurve() const
+  {
+    return myC3D;
+  }
+
+  //! Returns orientation of the edge
+  TopAbs_Orientation GetOrientation() const
+  {
+    return myOri;
+  }
+
+  //! Returns 2D-curve of the edge on mySurf
+  const Geom2dAdaptor_Curve& Get2DCurve() const
+  {
+    return myC2D;
+  }
+
+  //! Returns surface
+  const GeomAdaptor_Surface& GetSurface() const
+  {
+    return mySurf;
+  }
+
+  //! Returns TRUE if the edge is pseudo
+  Standard_Boolean IsPseudo() const
+  {
+    return (myC3D.GetType() == GeomAbs_OtherCurve);
+  }
+
+  //! Returns TRUE if the edge has not been
+  //! initialized yet.
+  Standard_Boolean IsNull() const
+  {
+    return (myC2D.GetType() == GeomAbs_OtherCurve);
+  }
+
+  //! Returns first parameter of the curve of the edge
+  Standard_Real FirstParameter() const
+  {
+    return myC2D.FirstParameter();
+  }
+
+  //! Returns last parameter of the curve of the edge
+  Standard_Real LastParameter() const
+  {
+    return myC2D.LastParameter();
+  }
+
+  //! Returns vertex in the start position of the edge
+  const TopClass_GeomVertex& FirstVertex() const
+  {
+    return myVertF;
+  }
+
+  //! Returns vertex in the end of the edge
+  const TopClass_GeomVertex& LastVertex() const
+  {
+    return myVertL;
+  }
+
+  //! Returns topological representation
+  //! of the edge. Uses only in TopOpeBRep classes.
+  const TopoDS_Edge& GetTopoEdge() const
+  {
+    return myTopoEdge;
+  }
+
+  Standard_Boolean IsSameParameter() const
+  {
+    return myIsSameParameter;
+  }
+
+protected:
+
+  //! Initializes of fields
+  void Init(const Handle(Geom_Curve)& theC3D,
+            const Handle(Geom2d_Curve)& theC2D,
+            const Handle(Geom_Surface)& theS,
+            const Standard_Real theFirstParam,
+            const Standard_Real theLastParam);
+
+private:
+  //! This field is used for compatibility with TopOpeBRep classes
+  //! and must be deleted after these classes will be eliminated.
+  TopoDS_Edge myTopoEdge;
+
+  //! 3D-curve of the edge
+  GeomAdaptor_Curve myC3D;
+
+  //! 2D-curve of the edge
+  Geom2dAdaptor_Curve myC2D;
+
+  //! Surface, which lies 2D-curve on
+  GeomAdaptor_Surface mySurf;
+
+  //! Orientation of the edge
+  TopAbs_Orientation myOri;
+  
+  //! Vertex in the start position of the edge
+  TopClass_GeomVertex myVertF;
+
+  //! Vertex in the end of the edge
+  TopClass_GeomVertex myVertL;
+
+  //! Is equal to TRUE if myC3D and myC2D
+  //! are same-parameter.
+  Standard_Boolean myIsSameParameter;
+};
+
+#endif
\ No newline at end of file
diff --git a/src/TopClass/TopClass_GeomVertex.cxx b/src/TopClass/TopClass_GeomVertex.cxx
new file mode 100644
index 0000000..6242f3b
--- /dev/null
+++ b/src/TopClass/TopClass_GeomVertex.cxx
@@ -0,0 +1,52 @@
+// Created on: 2017-02-17
+// Created by: Nikolai BUKHALOV
+// Copyright (c) 1999-2017 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#include <TopClass_GeomVertex.hxx>
+
+#include <BRep_Tool.hxx>
+#include <TopoDS_Vertex.hxx>
+
+//=======================================================================
+//function : Init
+//purpose  : 
+//=======================================================================
+void TopClass_GeomVertex::Init(const TopoDS_Vertex &theV,
+                               const TopoDS_Edge   &theE)
+{
+  if (theV.IsNull())
+    return;
+
+  // If theV.IsNull() == TRUE then BRep_Tool::Parameter(...)
+  // throws exception.
+  Init(theV, BRep_Tool::Parameter(theV, theE));
+}
+
+//=======================================================================
+//function : Init
+//purpose  : 
+//=======================================================================
+void TopClass_GeomVertex::Init(const TopoDS_Vertex &theV,
+                               const Standard_Real theParameterOnEdge)
+{
+  if (theV.IsNull())
+    return;
+
+  // If theV.IsNull() == TRUE then BRep_Tool::Tolerance(...) and
+  // BRep_Tool::Pnt(...) throw exception.
+
+  myEdgeParameter = theParameterOnEdge;
+  myToler = BRep_Tool::Tolerance(theV);
+  myPoint = BRep_Tool::Pnt(theV);  
+}
diff --git a/src/TopClass/TopClass_GeomVertex.hxx b/src/TopClass/TopClass_GeomVertex.hxx
new file mode 100644
index 0000000..c337f77
--- /dev/null
+++ b/src/TopClass/TopClass_GeomVertex.hxx
@@ -0,0 +1,111 @@
+// Created on: 2017-02-17
+// Created by: Nikolai BUKHALOV
+// Copyright (c) 1999-2017 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef _TopClass_GeomVertex_HeaderFile
+#define _TopClass_GeomVertex_HeaderFile
+
+#include <Standard_Type.hxx>
+
+#include <gp_Pnt.hxx>
+
+class TopoDS_Edge;
+class TopoDS_Vertex;
+
+//! Stores geometrical information about TopoDS_Vertex,
+//! which is useful for TopClass_GeomEdge class only.
+//! ATTENTION!!! This geometrical representation
+//! does not store any information about sharing this
+//! vertex between several edges. I.e. one geom vertex
+//! is in single geom-edge only.
+
+class TopClass_GeomVertex
+{
+public:
+  //! Default constructor
+  TopClass_GeomVertex() : myToler(-1.0), myEdgeParameter(0.0){}
+
+  //! It is main constructor for initialization of
+  //! this class.
+  TopClass_GeomVertex(const TopoDS_Vertex &theV,
+                      const TopoDS_Edge   &theE)
+  {
+    Init(theV, theE);
+  }
+
+  //! This constructor is used for pseudo-edges (which do not have
+  //! any 3D-representations).
+  TopClass_GeomVertex(const TopoDS_Vertex &theV,
+                      const Standard_Real theParameterOnEdge)
+  {
+    Init(theV, theParameterOnEdge);
+  }
+
+  //! It is main method for initialization of
+  //! this class.
+  Standard_EXPORT void Init(const TopoDS_Vertex &theV,
+                            const TopoDS_Edge   &theE);
+
+  //! This method is used for initialization of pseudo-edges
+  //! (which do not have any 3D-representations).
+  Standard_EXPORT void Init(const TopoDS_Vertex &theV,
+                            const Standard_Real theParameterOnEdge);
+
+  //! Returns TRUE for not initialized object
+  Standard_Boolean IsNull() const
+  {
+    return (myToler < 0.0);
+  }
+
+  //! Returns TRUE if theP is covered by *this
+  Standard_Boolean IsSame(const gp_Pnt& theP) const
+  {
+    if (IsNull())
+      return Standard_False;
+
+    return (theP.SquareDistance(myPoint) < myToler*myToler);
+  }
+
+  //! Returns the parameter of the vertex on the edge.
+  Standard_Real ParameterOnEdge() const
+  {
+    return myEdgeParameter;
+  }
+
+  //! Returns the tolerance of the vertex.
+  Standard_Real Tolerance() const
+  {
+    return myToler;
+  }
+
+  //! Returns 3D-point of the vertex.
+  const gp_Pnt& GetPnt3D() const
+  {
+    return myPoint;
+  }
+
+protected:
+
+private:
+  //! 3D-point of the vertex
+  gp_Pnt myPoint;
+  
+  //! Tolerance of the vertex
+  Standard_Real myToler;
+
+  //! Parameter of the vertex on the edge.
+  Standard_Real myEdgeParameter;
+};
+
+#endif
\ No newline at end of file
diff --git a/src/TopClass/TopClass_RayInfo.hxx b/src/TopClass/TopClass_RayInfo.hxx
new file mode 100644
index 0000000..d9f9348
--- /dev/null
+++ b/src/TopClass/TopClass_RayInfo.hxx
@@ -0,0 +1,164 @@
+// Created on: 2017-02-17
+// Created by: Nikolai BUKHALOV
+// Copyright (c) 1999-2017 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef _TopClass_RayInfo_HeaderFile
+#define _TopClass_RayInfo_HeaderFile
+
+#include <Standard_Type.hxx>
+
+#include <gp_Lin2d.hxx>
+#include <TopAbs_State.hxx>
+
+//! Describes classification ray, which is directed from
+//! the classified point to some point on an edge of
+//! the classification face.
+class TopClass_RayInfo
+{
+public:
+  //! Default constructor
+  TopClass_RayInfo() :myParam(RealLast()), myClassifState(TopAbs_UNKNOWN), myWeight(0)
+  {
+    myLParamArrs[0] = RealLast();
+    myLParamArrs[1] = RealLast();
+  }
+
+  //! Sets line of the ray
+  void SetLin(const gp_Lin2d& theL)
+  {
+    myLin = theL;
+  }
+
+  //! Sets parameter on the edge corresponding to the intersection
+  //! point between the ray and the edge.
+  void SetParameter(const Standard_Real theParam)
+  {
+    myParam = theParam;
+  }
+
+  //! Sets classification state of the ray.
+  //! This state will be applied as classification result
+  //! if the ray is valid.
+  void SetState(const TopAbs_State theState)
+  {
+    myClassifState = theState;
+  }
+
+  //! Returns line of the ray
+  const gp_Lin2d& GetLine() const
+  {
+    return myLin;
+  }
+
+  //! Returns parameter on the edge correspond to the intersection
+  //! point between the ray and the edge.
+  Standard_Real GetParameter() const
+  {
+    return myParam;
+  }
+
+  //! Returns classification state of the ray.
+  TopAbs_State GetState() const
+  {
+    return myClassifState;
+  }
+
+  //! Returns the weight of the ray.
+  //! Allows determining to what extent this ray
+  //! is valid.
+  unsigned int GetWeight() const
+  {
+    return myWeight;
+  }
+
+  //! Increments myWeight.
+  //! ATTENTION !!! It is impossible to decrease
+  //! this value.
+  void AddPenalty(const unsigned int theWeight = 1)
+  {
+    if (myWeight < (myMaximalWeight - theWeight))
+    {
+      myWeight += theWeight;
+    }
+    else
+    {
+      myWeight = myMaximalWeight;
+    }
+  }
+
+  //! Remember parameter of intersection with an edge
+  void AddParamOnLine(const Standard_Real thePrm)
+  {
+    if (thePrm >= myLParamArrs[1])
+      return;
+
+    if (thePrm < myLParamArrs[0])
+    {
+      myLParamArrs[1] = myLParamArrs[0];
+      myLParamArrs[0] = thePrm;
+    }
+    else
+    {
+      myLParamArrs[1] = thePrm;
+    }
+  }
+
+  //! Comparator method for sorting
+  bool operator<(const TopClass_RayInfo& theOther) const
+  {
+    return myWeight < theOther.myWeight;
+  }
+
+  //! Returns thickness of the section of the face by the ray.
+  //! If the section contains several disconnected regions
+  //! nearest region to the classification point will be taken.
+  Standard_Real MinDeltaInterval() const
+  {
+    if (myLParamArrs[0] == RealLast())
+      return RealLast();
+
+    return (myLParamArrs[1] - myLParamArrs[0]);
+  }
+
+private:
+  //! Ray-direction
+  gp_Lin2d myLin;
+
+  //! Parameter on myLin determined
+  //! by intersection point of myLin
+  //! and the edge.
+  Standard_Real myParam;
+
+  //! Classification state of the ray.
+  //! This state will be applied as classification result
+  //! if the ray is valid.
+  TopAbs_State myClassifState;
+
+  //! 0 if the segment is valid.
+  //! It is incremented
+  //! with every observed abnormality.
+  unsigned int myWeight;
+
+  //! Maximal value for unsigned int type
+  static const unsigned int myMaximalWeight = UINT_MAX;
+
+  //! Stores parameters on myLin correspond to the intersection
+  //! point between this ray and the edges.
+  //! If there are many intersection points then two nearest
+  //! to the classification point will be taken.
+  //! This array is always sorted in ascending order.
+  Standard_Real myLParamArrs[2];
+};
+
+#endif
\ No newline at end of file
diff --git a/src/TopOpeBRep/TopOpeBRep_PointClassifier.cxx b/src/TopOpeBRep/TopOpeBRep_PointClassifier.cxx
index edec333..7072510 100644
--- a/src/TopOpeBRep/TopOpeBRep_PointClassifier.cxx
+++ b/src/TopOpeBRep/TopOpeBRep_PointClassifier.cxx
@@ -66,14 +66,13 @@ void TopOpeBRep_PointClassifier::Load(const TopoDS_Face& F)
 //purpose  : 
 //=======================================================================
 
-TopAbs_State TopOpeBRep_PointClassifier::Classify
-  (const TopoDS_Face& F, 
-   const gp_Pnt2d& P2d, 
-   const Standard_Real Tol)
+TopAbs_State TopOpeBRep_PointClassifier::Classify(const TopoDS_Face& F, 
+                                                  const gp_Pnt2d& P2d, 
+                                                  const Standard_Real theTol3D)
 {
   myState = TopAbs_UNKNOWN;
   Load(F);
-  myState = myTopolTool->Classify(P2d,Tol);
+  myState = myTopolTool->Classify(P2d, theTol3D);
 
   return myState;
 }
diff --git a/src/TopOpeBRep/TopOpeBRep_PointClassifier.hxx b/src/TopOpeBRep/TopOpeBRep_PointClassifier.hxx
index a4248d4..ba9f6f3 100644
--- a/src/TopOpeBRep/TopOpeBRep_PointClassifier.hxx
+++ b/src/TopOpeBRep/TopOpeBRep_PointClassifier.hxx
@@ -45,7 +45,7 @@ public:
   Standard_EXPORT void Load (const TopoDS_Face& F);
   
   //! compute position of point <P> regarding with the face <F>.
-  Standard_EXPORT TopAbs_State Classify (const TopoDS_Face& F, const gp_Pnt2d& P, const Standard_Real Tol);
+  Standard_EXPORT TopAbs_State Classify (const TopoDS_Face& F, const gp_Pnt2d& P, const Standard_Real Tol3D);
   
   Standard_EXPORT TopAbs_State State() const;
 
diff --git a/src/TopOpeBRep/TopOpeBRep_VPointInterClassifier.cxx b/src/TopOpeBRep/TopOpeBRep_VPointInterClassifier.cxx
index 4b6d414..087e8d5 100644
--- a/src/TopOpeBRep/TopOpeBRep_VPointInterClassifier.cxx
+++ b/src/TopOpeBRep/TopOpeBRep_VPointInterClassifier.cxx
@@ -61,7 +61,7 @@ TopAbs_State TopOpeBRep_VPointInterClassifier::VPointPosition
  const Standard_Integer FaceClassifyIndex,
  TopOpeBRep_PointClassifier& PC,
  const Standard_Boolean AssumeINON,
- const Standard_Real Tol)
+ const Standard_Real theTol3D)
 {
   myState = TopAbs_UNKNOWN;
 
@@ -101,7 +101,7 @@ TopAbs_State TopOpeBRep_VPointInterClassifier::VPointPosition
   TopoDS_Face FF = TopoDS::Face(F);
   TopOpeBRepTool_ShapeTool::AdjustOnPeriodic(FF,u,v);
   gp_Pnt2d p2d(u,v);
-  TopAbs_State statefast = PC.Classify(FF,p2d,Tol);
+  TopAbs_State statefast = PC.Classify(FF, p2d, theTol3D);
   myState = statefast;
   VP.State(myState,FaceClassifyIndex);
 
@@ -109,14 +109,14 @@ TopAbs_State TopOpeBRep_VPointInterClassifier::VPointPosition
   // intersections est sur une frontiere de la face FF (ON)ou dans la face FF (IN)  
   Standard_Integer VPSI = VP.ShapeIndex();
   if (AssumeINON && FaceClassifyIndex == VPSI) {
-    mySlowFaceClassifier.Perform(FF,p2d,Tol);
+    mySlowFaceClassifier.Perform(FF, p2d, theTol3D);
     myState = mySlowFaceClassifier.State();
     if      (myState == TopAbs_ON) {
 //modified by NIZHNY-MKK  Mon Jun 19 11:45:36 2000.BEGIN
       myState = SlowClassifyOnBoundary(VP.Value(), p2d, mySlowFaceClassifier, FF);      
       if(myState == TopAbs_ON) {
 //modified by NIZHNY-MKK  Mon Jun 19 11:45:36 2000.END
-	VP.EdgeON(mySlowFaceClassifier.Edge().Edge(),
+	VP.EdgeON(mySlowFaceClassifier.Edge().GetTopoEdge(),
 		  mySlowFaceClassifier.EdgeParameter(),
 		  FaceClassifyIndex);
       }
@@ -130,14 +130,14 @@ TopAbs_State TopOpeBRep_VPointInterClassifier::VPointPosition
 
   else if (!AssumeINON) {
     if (statefast == TopAbs_OUT || statefast == TopAbs_ON) {
-      mySlowFaceClassifier.Perform(FF,p2d,Tol);
+      mySlowFaceClassifier.Perform(FF, p2d, theTol3D);
       myState = mySlowFaceClassifier.State();
       if      (myState == TopAbs_ON) {
 //modified by NIZHNY-MKK  Mon Jun 19 11:45:36 2000.BEGIN
 	myState = SlowClassifyOnBoundary(VP.Value(), p2d, mySlowFaceClassifier, FF);
 	if(myState == TopAbs_ON) {
 //modified by NIZHNY-MKK  Mon Jun 19 11:45:36 2000.END
-	  VP.EdgeON(mySlowFaceClassifier.Edge().Edge(),
+	  VP.EdgeON(mySlowFaceClassifier.Edge().GetTopoEdge(),
 		    mySlowFaceClassifier.EdgeParameter(),
 		    FaceClassifyIndex);
 	}
@@ -150,7 +150,7 @@ TopAbs_State TopOpeBRep_VPointInterClassifier::VPointPosition
     //modified by NIZNHY-PKV Mon Feb  5 19:04:01 2001 f
     if (statefast == TopAbs_ON || statefast == TopAbs_OUT) {
     //if (statefast == TopAbs_ON) {
-      mySlowFaceClassifier.Perform(FF, p2d, Tol);
+      mySlowFaceClassifier.Perform(FF, p2d, theTol3D);
       myState = mySlowFaceClassifier.State();
       
       if (myState == TopAbs_ON || myState == TopAbs_OUT) {
@@ -158,7 +158,7 @@ TopAbs_State TopOpeBRep_VPointInterClassifier::VPointPosition
       //modified by NIZNHY-PKV Mon Feb  5 19:04:49 2001 t
 	myState = SlowClassifyOnBoundary(VP.Value(), p2d, mySlowFaceClassifier, FF);
 	if(myState==TopAbs_ON) {
-	  VP.EdgeON(mySlowFaceClassifier.Edge().Edge(),
+	  VP.EdgeON(mySlowFaceClassifier.Edge().GetTopoEdge(),
 		    mySlowFaceClassifier.EdgeParameter(),
 		    FaceClassifyIndex);
 	}
@@ -179,7 +179,7 @@ TopAbs_State TopOpeBRep_VPointInterClassifier::VPointPosition
 const TopoDS_Shape& TopOpeBRep_VPointInterClassifier::Edge() const
 {
   if (myState == TopAbs_ON) {
-    const TopoDS_Shape& S = mySlowFaceClassifier.Edge().Edge();
+    const TopoDS_Shape& S = mySlowFaceClassifier.Edge().GetTopoEdge();
     return S;
   }
   else {
@@ -210,7 +210,7 @@ static TopAbs_State SlowClassifyOnBoundary(const gp_Pnt& thePointToClassify,
 					   const TopoDS_Face& theFace) {   
 
   Standard_Real aParameterOnEdge = theSlowClassifier.EdgeParameter();
-  const TopoDS_Edge& anEdge = theSlowClassifier.Edge().Edge();
+  const TopoDS_Edge& anEdge = theSlowClassifier.Edge().GetTopoEdge();
 
   Standard_Real parf, parl;
   Handle(Geom_Curve) anEdgeCurve = BRep_Tool::Curve(anEdge, parf, parl);
@@ -247,6 +247,8 @@ static TopAbs_State SlowClassifyOnBoundary(const gp_Pnt& thePointToClassify,
 	  
       if(!anEdgePCurve.IsNull()) {
 	gp_Pnt2d aPoint2dOnEdge = anEdgePCurve->Value(aParameterOnEdge);
+
+        // Must be 3D-tolerance. But we keep the current value.
 	Standard_Real aTol2d = thePoint2dToClassify.Distance(aPoint2dOnEdge) / 3;
 	theSlowClassifier.Perform(theFace, thePoint2dToClassify, aTol2d);
 	if(theSlowClassifier.State() == TopAbs_IN)
diff --git a/src/TopOpeBRepBuild/TopOpeBRepBuild_Builder1.cxx b/src/TopOpeBRepBuild/TopOpeBRepBuild_Builder1.cxx
index 239b136..5b06dc9 100644
--- a/src/TopOpeBRepBuild/TopOpeBRepBuild_Builder1.cxx
+++ b/src/TopOpeBRepBuild/TopOpeBRepBuild_Builder1.cxx
@@ -20,6 +20,7 @@
 #include <BRepTopAdaptor_FClass2d.hxx>
 #include <Geom2d_Curve.hxx>
 #include <Geom2dAPI_ProjectPointOnCurve.hxx>
+#include <Precision.hxx>
 #include <TColStd_MapOfInteger.hxx>
 #include <TopAbs_Orientation.hxx>
 #include <TopAbs_ShapeEnum.hxx>
@@ -1952,7 +1953,7 @@ static TopAbs_State ClassifyEdgeToFaceByOnePoint(const TopoDS_Edge& E,
 
   C2D -> D0(par, aP2d);
 
-  BRepTopAdaptor_FClass2d FC(F, 1e-7);
+  BRepTopAdaptor_FClass2d FC(F, Precision::Confusion());
   TopAbs_State aState = FC.Perform(aP2d);
 
   return aState;
diff --git a/src/TopOpeBRepBuild/TopOpeBRepBuild_GridSS.cxx b/src/TopOpeBRepBuild/TopOpeBRepBuild_GridSS.cxx
index 09aff15..9a66770 100644
--- a/src/TopOpeBRepBuild/TopOpeBRepBuild_GridSS.cxx
+++ b/src/TopOpeBRepBuild/TopOpeBRepBuild_GridSS.cxx
@@ -17,7 +17,6 @@
 
 #include <BRep_Tool.hxx>
 #include <BRepAdaptor_Surface.hxx>
-#include <BRepClass_Edge.hxx>
 #include <BRepClass_Intersector.hxx>
 #include <BRepTools.hxx>
 #include <ElCLib.hxx>
@@ -77,6 +76,7 @@
 #include <TopOpeBRepTool_ShapeExplorer.hxx>
 #include <TopOpeBRepTool_ShapeTool.hxx>
 #include <TopOpeBRepTool_TOOL.hxx>
+#include <TopClass_GeomEdge.hxx>
 
 #ifdef DRAW
 #include <TopOpeBRepTool_DRAW.hxx>
@@ -1309,8 +1309,6 @@ static Standard_Boolean AreFacesCoincideInArea (const TopoDS_Shape& theBaseFace,
   Standard_Real pLinMin = RealLast();
   Standard_Real tol2d = Precision::PConfusion();
   BRepClass_Intersector anInter;
-  BRepClass_Edge aBCE;
-  aBCE.Face() = aBaseFace;
   Standard_Real maxDist = Max (BRep_Tool::Tolerance(aBaseFace),
                                BRep_Tool::Tolerance(aFace));
 
@@ -1331,8 +1329,9 @@ static Standard_Boolean AreFacesCoincideInArea (const TopoDS_Shape& theBaseFace,
       if (PC.IsNull()) {isError = Standard_True; break;}
       BB.UpdateEdge(aE,PC,aBaseFace,tolE);
     }
-    aBCE.Edge() = aE;
-    anInter.Perform(aLin,pLinMin,tol2d,aBCE);
+
+    TopClass_GeomEdge aGE(aE, BRep_Tool::Surface(aBaseFace), PC, pf, pl);
+    anInter.Perform(aLin, pLinMin, Precision::PConfusion(), aGE);
     if (anInter.IsDone()) {
       Standard_Integer i;
       for (i=1; i <= anInter.NbPoints(); i++) {
diff --git a/src/TopOpeBRepBuild/TopOpeBRepBuild_Tools.cxx b/src/TopOpeBRepBuild/TopOpeBRepBuild_Tools.cxx
index 4ee0bba..5c463f4 100644
--- a/src/TopOpeBRepBuild/TopOpeBRepBuild_Tools.cxx
+++ b/src/TopOpeBRepBuild/TopOpeBRepBuild_Tools.cxx
@@ -481,7 +481,7 @@ void TopOpeBRepBuild_Tools::GetNormalInNearestPoint(const TopoDS_Face& F,
 
   
   gp_Pnt2d aP2d(newU, newV);
-  BRepTopAdaptor_FClass2d FC(F, Precision::PConfusion());
+  BRepTopAdaptor_FClass2d FC(F, Precision::Confusion());
   TopAbs_State aState = FC.Perform(aP2d);
 
   //point out of face: try to go at another direction
diff --git a/src/TopOpeBRepBuild/TopOpeBRepBuild_WireEdgeClassifier.cxx b/src/TopOpeBRepBuild/TopOpeBRepBuild_WireEdgeClassifier.cxx
index 099ef2c..e90a907 100644
--- a/src/TopOpeBRepBuild/TopOpeBRepBuild_WireEdgeClassifier.cxx
+++ b/src/TopOpeBRepBuild/TopOpeBRepBuild_WireEdgeClassifier.cxx
@@ -33,6 +33,7 @@
 #include <TopExp_Explorer.hxx>
 #include <BRep_Tool.hxx>
 #include <Geom2d_Curve.hxx>
+#include <BRepAdaptor_Surface.hxx>
 #include <BRepClass_FaceClassifier.hxx>
 #include <Standard_ProgramError.hxx>
 #include <Geom_Curve.hxx>
@@ -51,6 +52,7 @@
 
 #include <TopOpeBRepBuild_Builder.hxx>
 #include <TopOpeBRepBuild_define.hxx>
+#include <TopClass_GeomEdge.hxx>
 
 #ifdef OCCT_DEBUG
 static TCollection_AsciiString PRODINS("dins ");
@@ -75,7 +77,7 @@ TopOpeBRepBuild_WireEdgeClassifier::TopOpeBRepBuild_WireEdgeClassifier
  const TopOpeBRepBuild_BlockBuilder& BB) :
 TopOpeBRepBuild_CompositeClassifier(BB)
 {
-  myBCEdge.Face() = TopoDS::Face(F);
+  myFace = TopoDS::Face(F);
 }
 
 //=======================================================================
@@ -172,7 +174,7 @@ TopoDS_Shape TopOpeBRepBuild_WireEdgeClassifier::LoopToShape(const Handle(TopOpe
   Bit.Initialize();
   if ( !Bit.More() ) return myShape;
 
-  TopoDS_Shape aLocalShape = myBCEdge.Face();
+  TopoDS_Shape aLocalShape = myFace;
   const TopoDS_Face& F1 = TopoDS::Face(aLocalShape);
 //  const TopoDS_Face& F1 = TopoDS::Face(myBCEdge.Face());
   aLocalShape = F1.EmptyCopied();
@@ -281,11 +283,10 @@ TopAbs_State  TopOpeBRepBuild_WireEdgeClassifier::CompareShapes
       const TopoDS_Edge& E2 = TopoDS::Edge(ex2.Current());
       if (mape1.Contains(E2)) continue;
       
-      const TopoDS_Face& theFace =  myBCEdge.Face();
       BRep_Builder BB; 
 
       // p2d on E2 of B2, E2 not shared by B1
-      TopoDS_Shape aLocalShape = theFace.Oriented(TopAbs_FORWARD);
+      TopoDS_Shape aLocalShape = myFace.Oriented(TopAbs_FORWARD);
       TopoDS_Face ftmp = TopoDS::Face(aLocalShape);
 //      TopoDS_Face ftmp = TopoDS::Face(theFace.Oriented(TopAbs_FORWARD));
       aLocalShape = ftmp.EmptyCopied();
@@ -302,7 +303,7 @@ TopAbs_State  TopOpeBRepBuild_WireEdgeClassifier::CompareShapes
 //      TopoDS_Face F1 = TopoDS::Face(ftmp.EmptyCopied());
       BB.Add(F1,TopoDS::Wire(B1));
 
-      Standard_Real tolF1 = BRep_Tool::Tolerance(F1);
+      const Standard_Real tolF1 = BRep_Tool::Tolerance(F1);
       BRepClass_FaceClassifier Fclass(F1, p2d, tolF1);
       state = Fclass.State();
       return state;
@@ -380,17 +381,16 @@ void  TopOpeBRepBuild_WireEdgeClassifier::ResetShape(const TopoDS_Shape& B)
 void  TopOpeBRepBuild_WireEdgeClassifier::ResetElement(const TopoDS_Shape& EE)
 {
   const TopoDS_Edge& E = TopoDS::Edge(EE);
-  const TopoDS_Face& F = myBCEdge.Face();
   Standard_Real f2,l2,tolpc;Handle(Geom2d_Curve) C2D; //jyl980406+
-  Standard_Boolean haspc = FC2D_HasCurveOnSurface(E,F); //jyl980406+
+  Standard_Boolean haspc = FC2D_HasCurveOnSurface(E, myFace); //jyl980406+
   if (!haspc) { //jyl980406+
-    Standard_Boolean trim3d = Standard_True; C2D = FC2D_CurveOnSurface(E,F,f2,l2,tolpc,trim3d); //jyl980406+
+    Standard_Boolean trim3d = Standard_True; C2D = FC2D_CurveOnSurface(E, myFace, f2, l2, tolpc, trim3d); //jyl980406+
     Standard_Real tolE = BRep_Tool::Tolerance(E); //jyl980406+  
     Standard_Real tol = Max(tolE,tolpc); //jyl980406+
-    BRep_Builder BB; BB.UpdateEdge(E,C2D,F,tol); //jyl980406+
+    BRep_Builder BB; BB.UpdateEdge(E, C2D, myFace, tol); //jyl980406+
   } //jyl980406+
   
-  C2D = FC2D_CurveOnSurface(E,F,f2,l2,tolpc);
+  C2D = FC2D_CurveOnSurface(E, myFace, f2, l2, tolpc);
   if (C2D.IsNull()) throw Standard_ProgramError("WEC : ResetElement");
 
   Standard_Real t = 0.397891143689; Standard_Real par = ((1-t)*f2 + t*l2);
@@ -414,20 +414,22 @@ Standard_Boolean TopOpeBRepBuild_WireEdgeClassifier::CompareElement(const TopoDS
 {
   Standard_Boolean bRet = Standard_True;
   const TopoDS_Edge& E = TopoDS::Edge(EE);
-  const TopoDS_Face& F = myBCEdge.Face();
 
   Standard_Real f2,l2,tolpc;Handle(Geom2d_Curve) C2D; //jyl980402+
-  Standard_Boolean haspc = FC2D_HasCurveOnSurface(E,F); //jyl980402+
+  Standard_Boolean haspc = FC2D_HasCurveOnSurface(E, myFace); //jyl980402+
   if (!haspc) { //jyl980402+
-    Standard_Boolean trim3d = Standard_True; C2D = FC2D_CurveOnSurface(E,F,f2,l2,tolpc,trim3d); //jyl980406+
+    Standard_Boolean trim3d = Standard_True;
+    C2D = FC2D_CurveOnSurface(E, myFace, f2, l2, tolpc, trim3d); //jyl980406+
     // C2D = FC2D_CurveOnSurface(E,F,f2,l2,tolpc,trim3d); //jyl980406-
     Standard_Real tolE = BRep_Tool::Tolerance(E); //jyl980402+  
     Standard_Real tol = Max(tolE,tolpc); //jyl980402+
-    BRep_Builder BB; BB.UpdateEdge(E,C2D,F,tol); //jyl980402+
+    BRep_Builder BB; 
+    BB.UpdateEdge(E, C2D, myFace, tol); //jyl980402+
   } //jyl980402+
+  else
+    C2D = FC2D_CurveOnSurface(E, myFace, f2, l2, tolpc);
 
   if (myFirstCompare) {
-    C2D = FC2D_CurveOnSurface(E,F,f2,l2,tolpc);
     Standard_Real t = 0.33334567; Standard_Real par = ((1-t)*f2 + t*l2);
     gp_Pnt2d p2d = C2D->Value(par);
     
@@ -441,14 +443,12 @@ Standard_Boolean TopOpeBRepBuild_WireEdgeClassifier::CompareElement(const TopoDS
     gp_Vec2d v2d(myPoint2d,p2d);
     gp_Lin2d l2d(myPoint2d,v2d);
     Standard_Real dist = myPoint2d.Distance(p2d);
-    Standard_Real tol2d = Precision::PConfusion(); // NYI : a voir
-    myFPC.Reset(l2d,dist,tol2d);
+    myFPC.Reset(l2d,dist);
     myFirstCompare = Standard_False;
   }
   
-  myBCEdge.Edge() = E;
-  TopAbs_Orientation Eori = E.Orientation();
-  myFPC.Compare(myBCEdge,Eori);
+  TopClass_GeomEdge aGE(E, BRep_Tool::Surface(myFace), C2D, f2, l2);
+  myFPC.Compare(aGE, Precision::PConfusion());
 #ifdef OCCT_DEBUG
 //  TopAbs_State state = myFPC.State();
 #endif
diff --git a/src/TopOpeBRepBuild/TopOpeBRepBuild_WireEdgeClassifier.hxx b/src/TopOpeBRepBuild/TopOpeBRepBuild_WireEdgeClassifier.hxx
index feb7b31..63a2d30 100644
--- a/src/TopOpeBRepBuild/TopOpeBRepBuild_WireEdgeClassifier.hxx
+++ b/src/TopOpeBRepBuild/TopOpeBRepBuild_WireEdgeClassifier.hxx
@@ -23,9 +23,9 @@
 
 #include <Standard_Boolean.hxx>
 #include <gp_Pnt2d.hxx>
-#include <BRepClass_Edge.hxx>
-#include <BRepClass_FacePassiveClassifier.hxx>
+#include <BRepClass_FClass2dOfFClassifier.hxx>
 #include <TopoDS_Shape.hxx>
+#include <TopoDS_Face.hxx>
 #include <TopOpeBRepBuild_CompositeClassifier.hxx>
 #include <TopAbs_State.hxx>
 class TopoDS_Shape;
@@ -88,8 +88,8 @@ private:
 
   Standard_Boolean myFirstCompare;
   gp_Pnt2d myPoint2d;
-  BRepClass_Edge myBCEdge;
-  BRepClass_FacePassiveClassifier myFPC;
+  TopoDS_Face myFace;
+  BRepClass_FClass2dOfFClassifier myFPC;
   TopoDS_Shape myShape;
 
 
diff --git a/src/TopOpeBRepBuild/TopOpeBRepBuild_ffsfs.cxx b/src/TopOpeBRepBuild/TopOpeBRepBuild_ffsfs.cxx
index 21e1082..32e37d6 100644
--- a/src/TopOpeBRepBuild/TopOpeBRepBuild_ffsfs.cxx
+++ b/src/TopOpeBRepBuild/TopOpeBRepBuild_ffsfs.cxx
@@ -96,7 +96,8 @@ static Standard_Integer FUN_getAncestorFsp(TopOpeBRepBuild_Builder& B,TopOpeBRep
       if (!ok) return 0;
       Standard_Real tolf = BRep_Tool::Tolerance(f)*1.e1;
       if (dd > tolf) return 0;
-      Standard_Real  TolClass  = 1e-8; BRepTopAdaptor_FClass2d FClass2d(f,TolClass);
+      Standard_Real  TolClass  = 1e-8;
+      BRepTopAdaptor_FClass2d FClass2d(f,TolClass);
       st = FClass2d.Perform(p2d);
     }
     if (st == TopAbs_IN) {
diff --git a/src/TopOpeBRepTool/TopOpeBRepTool_CLASSI.cxx b/src/TopOpeBRepTool/TopOpeBRepTool_CLASSI.cxx
index 5de0450..fa5977d 100644
--- a/src/TopOpeBRepTool/TopOpeBRepTool_CLASSI.cxx
+++ b/src/TopOpeBRepTool/TopOpeBRepTool_CLASSI.cxx
@@ -257,8 +257,7 @@ Standard_Integer TopOpeBRepTool_CLASSI::Classip2d(const TopoDS_Shape& S1, const
   // recall : ffi1 and ffi2 are built on same face 
   // => ffi1(u1,v1) = ffi2(u1,v1)
   // ----------------------------
-  Standard_Real tol2d2 = TopOpeBRepTool_TOOL::TolUV(ffi2,BRep_Tool::Tolerance(ffi2));
-  BRepClass_FaceClassifier class2(ffi2,p2d1,tol2d2);
+  BRepClass_FaceClassifier class2(ffi2,p2d1,BRep_Tool::Tolerance(ffi2));
   TopAbs_State sta12 = class2.State();
   
   // staffi12 : only if !bnd2dUNK and stabnd2d12!=DIFF
@@ -296,8 +295,7 @@ Standard_Integer TopOpeBRepTool_CLASSI::Classip2d(const TopoDS_Shape& S1, const
     gp_Pnt2d p2d2(u2,v2);
 
     // sta21 : 
-    Standard_Real tol2d1 = TopOpeBRepTool_TOOL::TolUV(ffi1,BRep_Tool::Tolerance(ffi1));
-    BRepClass_FaceClassifier class1(ffi1,p2d2,tol2d1);
+    BRepClass_FaceClassifier class1(ffi1,p2d2,BRep_Tool::Tolerance(ffi1));
     TopAbs_State sta21 = class1.State();
 
     if (bnd2dUNK) {
diff --git a/src/TopOpeBRepTool/TopOpeBRepTool_ShapeClassifier.cxx b/src/TopOpeBRepTool/TopOpeBRepTool_ShapeClassifier.cxx
index a738177..5a997af 100644
--- a/src/TopOpeBRepTool/TopOpeBRepTool_ShapeClassifier.cxx
+++ b/src/TopOpeBRepTool/TopOpeBRepTool_ShapeClassifier.cxx
@@ -19,9 +19,8 @@
 #include <BRepAdaptor_Curve2d.hxx>
 #include <BRepAdaptor_Surface.hxx>
 #include <BRepClass3d_SolidExplorer.hxx>
-#include <BRepClass_Edge.hxx>
 #include <BRepClass_FaceClassifier.hxx>
-#include <BRepClass_FacePassiveClassifier.hxx>
+#include <BRepClass_FClass2dOfFClassifier.hxx>
 #include <BRepTopAdaptor_FClass2d.hxx>
 #include <Geom2d_Curve.hxx>
 #include <Geom_Curve.hxx>
@@ -665,134 +664,4 @@ Standard_Boolean TopOpeBRepTool_ShapeClassifier::HasAvLS() const
 {
   Standard_Boolean hasavls = (myPAvLS) ? (!myPAvLS->IsEmpty()) : Standard_False;
   return hasavls;
-}
-
-#if 0
-//=======================================================================
-//function : FindEdge
-//purpose  : 
-//=======================================================================
-
-void TopOpeBRepTool_ShapeClassifier::FindEdge(const TopoDS_Shape& S)
-{
-  myEdge.Nullify();
-  Standard_Boolean isavs = (! myAvS.IsNull());
-  Standard_Boolean isavls = HasAvLS();
-  Standard_Boolean isav = (isavs || isavls);
-
-  if (S.IsNull()) return;
-  TopAbs_ShapeEnum tS = S.ShapeType();
-
-  TopExp_Explorer eex;
-  if ( ! myFace.IsNull() ) eex.Init(myFace,TopAbs_EDGE);
-  else eex.Init(S,TopAbs_EDGE);
-
-  for(; eex.More(); eex.Next()) {
-    const TopoDS_Edge& E = TopoDS::Edge(eex.Current());
-    if ( isav ) {
-      Standard_Boolean toavoid = Standard_False;
-      if ( isavls ) toavoid = myMapAvS.Contains(E);
-      else if ( isavs )	toavoid = E.IsSame(myAvS);      
-      if ( toavoid ) continue;
-    }
-    else if ( BRep_Tool::Degenerated(E) ) {
-      if ( tS != TopAbs_EDGE ) continue;
-    }
-    myEdge = E;
-    break;
-  }
-}
-
-static Standard_Boolean FindAPointInTheFace
-(const TopoDS_Face& _face,gp_Pnt& APoint,Standard_Real& u,Standard_Real& v) 
-{ 
-  TopoDS_Face face=_face;
-  face.Orientation(TopAbs_FORWARD);
-
-  TopExp_Explorer     faceexplorer;
-  BRepAdaptor_Curve2d c;
-  gp_Vec2d T;
-  gp_Pnt2d P;
-  Standard_Boolean Ok = Standard_False;
-  Standard_Integer nbiter=0;
-  Standard_Real myParamOnEdge = 0.5;
-  do { 
-    nbiter++;
-    if(myParamOnEdge==0.5)  myParamOnEdge = 0.4;
-    else if(myParamOnEdge==0.4)  myParamOnEdge = 0.6; 
-    else if(myParamOnEdge==0.6)  myParamOnEdge = 0.3; 
-    else if(myParamOnEdge==0.3)  myParamOnEdge = 0.7; 
-    else if(myParamOnEdge==0.7)  myParamOnEdge = 0.2; 
-    else if(myParamOnEdge==0.2)  myParamOnEdge = 0.8; 
-    else if(myParamOnEdge==0.8)  myParamOnEdge = 0.1; 
-    else if(myParamOnEdge==0.1)  myParamOnEdge = 0.9;
-    else { myParamOnEdge*=0.5; } 
-    
-    for (faceexplorer.Init(face,TopAbs_EDGE); 
-	 faceexplorer.More(); 
-	 faceexplorer.Next()) {
-      TopoDS_Edge Edge = TopoDS::Edge(faceexplorer.Current());
-      c.Initialize(Edge,face);
-      Standard_Integer nbinterval = c.NbIntervals(GeomAbs_C1); 
-      c.D1((c.LastParameter() - c.FirstParameter()) * myParamOnEdge + c.FirstParameter(),P,T);
-      
-      Standard_Real x=T.X();
-      Standard_Real y=T.Y();
-      //-- cout<<"Param:"<<(c.IntervalFirst() + c.IntervalLast()) * param<<" U:"<<P.X()<<" V:"<<P.Y();
-      //-- cout<<" tguv x:"<<x<<" , y:"<<y<<endl;
-      
-      
-      if(Edge.Orientation() == TopAbs_FORWARD) { 
-	T.SetCoord(-y,x);
-      }
-      else { 
-	T.SetCoord(y,-x);
-      }
-      
-      Standard_Real ParamInit = RealLast();
-      Standard_Real TolInit   = 0.00001;
-      Standard_Boolean APointExist = Standard_False;
-      
-      BRepClass_FacePassiveClassifier FClassifier;
-      
-      T.Normalize();
-      P.SetCoord(P.X()+TolInit*T.X(),P.Y()+TolInit*T.Y());
-      FClassifier.Reset(gp_Lin2d(P,T),ParamInit,RealEpsilon());   //-- Longueur et Tolerance #######
-      
-      TopExp_Explorer otherfaceexplorer;
-      for (otherfaceexplorer.Init(face,TopAbs_EDGE); 
-	   otherfaceexplorer.More(); 
-	   otherfaceexplorer.Next()) {
-	TopoDS_Edge OtherEdge = TopoDS::Edge(otherfaceexplorer.Current());
-	if((OtherEdge.Orientation() == TopAbs_EXTERNAL)) { 
-	}
-	else { 
-	  BRepClass_Edge AEdge(OtherEdge,face);
-	  FClassifier.Compare(AEdge,OtherEdge.Orientation());
-	  if(FClassifier.ClosestIntersection()) { 
-	    //-- cout<<" ---> Edge : "<<FClassifier.Parameter()<<endl;
-	    if(ParamInit > FClassifier.Parameter()) { 
-	      ParamInit = FClassifier.Parameter();
-	      APointExist = Standard_True;
-	    }
-	  }
-	}
-      }
-      if(APointExist) { 
-	ParamInit*=0.5;
-	u = P.X() + ParamInit* T.X();
-	v = P.Y() + ParamInit* T.Y();
-	BRepAdaptor_Surface  s;
-	Standard_Boolean computerestriction = Standard_False;
-	s.Initialize(face,computerestriction);
-	s.D0(u,v,APoint);
-	//-- cout<<" u="<<u<<" v="<<v<<"  -> ("<<APoint.X()<<","<<APoint.Y()<<","<<APoint.Z()<<endl;
-	return(Standard_True);
-      }
-    }
-  }
-  while(nbiter<100);
-  return(Standard_False);
-}
-
-#endif
+}
\ No newline at end of file
diff --git a/src/TopOpeBRepTool/TopOpeBRepTool_face.cxx b/src/TopOpeBRepTool/TopOpeBRepTool_face.cxx
index bd3ba61..cf6ac64 100644
--- a/src/TopOpeBRepTool/TopOpeBRepTool_face.cxx
+++ b/src/TopOpeBRepTool/TopOpeBRepTool_face.cxx
@@ -18,6 +18,7 @@
 #include <BRep_Builder.hxx>
 #include <BRep_Tool.hxx>
 #include <BRepTopAdaptor_FClass2d.hxx>
+#include <gp.hxx>
 #include <Precision.hxx>
 #include <Standard_Failure.hxx>
 #include <TopoDS.hxx>
@@ -69,7 +70,7 @@ Standard_Boolean TopOpeBRepTool_face::Init(const TopoDS_Wire& W, const TopoDS_Fa
   B.NaturalRestriction(fres,Standard_True);
 
   // <myfinite> :
-  BRepTopAdaptor_FClass2d FClass(fres,0.);
+  BRepTopAdaptor_FClass2d FClass(fres, gp::Resolution());
   Standard_Boolean infinite = ( FClass.PerformInfinitePoint() == TopAbs_IN);
   myfinite = !infinite;
 
diff --git a/tests/blend/complex/A3 b/tests/blend/complex/A3
index e75b7d9..95f80f4 100644
--- a/tests/blend/complex/A3
+++ b/tests/blend/complex/A3
@@ -4,6 +4,9 @@
 ## Comment : from original bug PRO4497
 ## ====================================
 
+# Result contains the edge covered by the tolerance
+# of its vertices.
+
 restore [locate_data_file CCH_indushep.rle] s
 tscale s 0 0 0 1000
 explode s e
diff --git a/tests/blend/tolblend_simple/C1 b/tests/blend/tolblend_simple/C1
index 623f013..b01edde 100644
--- a/tests/blend/tolblend_simple/C1
+++ b/tests/blend/tolblend_simple/C1
@@ -14,6 +14,8 @@
 #sewing s t_1 t_5 t2_1 t2_5
 #explode s Sh
 
+puts "TODO OCC29236 All:TEST INCOMPLETE"
+
 restore [locate_data_file CFI_7_c3_fhq.rle] s
 tscale  s 0 0 0 SCALE1 
 explode s e
diff --git a/tests/boolean/bfuse_complex/M7 b/tests/boolean/bfuse_complex/M7
index 6e0fb49..452fa75 100644
--- a/tests/boolean/bfuse_complex/M7
+++ b/tests/boolean/bfuse_complex/M7
@@ -1,6 +1,10 @@
 # Original bug : cts20176
 # Date : 16July98
 
+#Shape a contains vertex with tolerance >50.
+#This vertex covers correspond edge completely.
+
+
 restore [locate_data_file CTO904_cts20176a.rle] a 
 restore [locate_data_file cts20176b.rle] b
 
diff --git a/tests/bugs/heal/bug22919 b/tests/bugs/heal/bug22919
index ac5add3..13e6e4f 100644
--- a/tests/bugs/heal/bug22919
+++ b/tests/bugs/heal/bug22919
@@ -1,4 +1,9 @@
-puts "TODO All: Faulty shapes in variables faulty_1 to faulty_"
+puts "REQUIRED OCC23731 All: Faulty shapes in variables faulty_1 to faulty_1"
+
+# IR-2017-09-07
+# ko2 and ko4 are shells containing two faces (despite ss_2 and ss_4 being single faces).
+# One face in every shell HAS TO be classified as invalid by checkshape (e.g. as
+# not closed, bad orientation etc. - please see explanation in the issue #28211).
 
 puts "========"
 puts "OCC22919"
diff --git a/tests/bugs/modalg_2/bug23341 b/tests/bugs/modalg_2/bug23341
deleted file mode 100755
index 98d44b3..0000000
--- a/tests/bugs/modalg_2/bug23341
+++ /dev/null
@@ -1,22 +0,0 @@
-puts "================"
-puts "OCC23341"
-puts "================"
-puts ""
-#######################################################################
-# Wrong result done by 2D classifier algorithm for a point and a face
-#######################################################################
-
-set BugNumber OCC23341
-
-restore [locate_data_file bug23341_f1] f1
-restore [locate_data_file bug23341_p] p
-set info [b2dclassify f1 p]
-set check [regexp "OUT" $info]
-
-if { ${check} == 1 } {
-    puts "OK ${BugNumber}"
-} else {
-    puts "Faulty ${BugNumber}"
-}
-
-
diff --git a/tests/bugs/modalg_5/bug23625_2 b/tests/bugs/modalg_5/bug23625_2
index 9d9fa86..18228b9 100755
--- a/tests/bugs/modalg_5/bug23625_2
+++ b/tests/bugs/modalg_5/bug23625_2
@@ -15,7 +15,7 @@ fit
 
 reflectlines result a 0 1 0
 
-checkprops result -l 3905.95 
+checkprops result -l 3977.19
 checkshape result 
 checksection result
 
diff --git a/tests/bugs/modalg_5/bug23777 b/tests/bugs/modalg_5/bug23777
deleted file mode 100755
index f02473f..0000000
--- a/tests/bugs/modalg_5/bug23777
+++ /dev/null
@@ -1,22 +0,0 @@
-puts "================"
-puts "OCC23777"
-puts "================"
-puts ""
-#######################################################################
-# 2D-Classifier algorithm produces wrong results for a point and face.
-#######################################################################
-
-set BugNumber OCC23777
-
-restore [locate_data_file bug23777_b1.brep] b1
-
-point p2D 0.062260538576946696 249583.00418413401
-
-set info [b2dclassify b1 p2D]
-set check [regexp "IN" $info]
-
-if { ${check} == 1 } {
-    puts "OK ${BugNumber}"
-} else {
-    puts "Faulty ${BugNumber}"
-}
diff --git a/tests/bugs/modalg_5/bug23849_2 b/tests/bugs/modalg_5/bug23849_2
deleted file mode 100644
index 8b87d96..0000000
--- a/tests/bugs/modalg_5/bug23849_2
+++ /dev/null
@@ -1,23 +0,0 @@
-puts "================"
-puts "OCC23849"
-puts "================"
-puts ""
-#######################################################################
-# BOP regression
-#######################################################################
-
-set BugNumber OCC23849
-
-restore [locate_data_file bug23849_segment_1.brep] b1
-explode b1 f
-
-point p2D 4.1882396063720497 50.643343428894831
-
-set info [b2dclassify b1_1 p2D]
-set check [regexp "ON" $info]
-
-if { ${check} == 1 } {
-    puts "OK ${BugNumber}"
-} else {
-    puts "Faulty ${BugNumber}"
-}
diff --git a/tests/bugs/modalg_5/bug24422 b/tests/bugs/modalg_5/bug24422
deleted file mode 100644
index d514c63..0000000
--- a/tests/bugs/modalg_5/bug24422
+++ /dev/null
@@ -1,27 +0,0 @@
-puts "================"
-puts "OCC24422"
-puts "================"
-puts ""
-#######################################################################
-# Wrong result done by FaceClassifier algorythm
-#######################################################################
-
-restore [locate_data_file bug24422_Compound.brep] b 
-explode b f
-copy b_1 f
-
-point p 115.945392440981 106 230.000108990528
-point p_proj 230.00010899052799 1925.9453924409811
-set info [b2dclassify f p_proj]
-
-if { [regexp "The point is OUT of shape" $info] != 1  } {
-    puts "Error : point should be ON shape"
-} else {
-    puts "OK: point is OUT of shape"
-}
-
-axo
-fit
-checkview -screenshot -2d -path ${imagedir}/${test_image}.png
-
-
diff --git a/tests/bugs/modalg_5/bug25969 b/tests/bugs/modalg_5/bug25969
deleted file mode 100644
index 4c190ff..0000000
--- a/tests/bugs/modalg_5/bug25969
+++ /dev/null
@@ -1,37 +0,0 @@
-puts "================"
-puts "CR25969"
-puts "================"
-puts ""
-###############################################
-## Wrong result obtained by 2d classifier algorithm.
-###############################################
-
-pload DCAF
-
-Open [locate_data_file bug25969_pal22851.cbf] D
-
-GetShape D 0:1:15:1:1:2 b1
-GetShape D 0:1:29:1:1:2 b2
- 
-explode b1
-explode b2
- 
-bop b1_2 b2_1
-bopcut r
-
-explode r f
-copy r_4 f
-pcurve f
- 
-point p 12.658283198213592 21.045164979270297 
- 
-set cls1 [b2dclassifx f p]
-if { [regexp {OUT} $cls1] } {
-    puts "Error : Wrong result of 2d classifier algorithm"
-} else {
-    puts "OK : Good result of 2d classifier algorithm"
-}
-
-smallview
-fit
-checkview -screenshot -2d -path ${imagedir}/${test_image}.png
diff --git a/tests/bugs/modalg_5/bug25969_std b/tests/bugs/modalg_5/bug25969_std
deleted file mode 100644
index a672786..0000000
--- a/tests/bugs/modalg_5/bug25969_std
+++ /dev/null
@@ -1,37 +0,0 @@
-puts "================"
-puts "CR25969"
-puts "================"
-puts ""
-###############################################
-## Wrong result obtained by 2d classifier algorithm.
-###############################################
-
-pload DCAF
-
-Open [locate_data_file bug25969_pal22851.sgd] D
-
-GetShape D 0:1:15:1:1:2 b1
-GetShape D 0:1:29:1:1:2 b2
- 
-explode b1
-explode b2
- 
-bop b1_2 b2_1
-bopcut r
-
-explode r f
-copy r_4 f
-pcurve f
- 
-point p 12.658283198213592 21.045164979270297 
- 
-set cls1 [b2dclassifx f p]
-if { [regexp {OUT} $cls1] } {
-    puts "Error : Wrong result of 2d classifier algorithm"
-} else {
-    puts "OK : Good result of 2d classifier algorithm"
-}
-
-smallview
-fit
-set only_screen_axo 1
diff --git a/tests/bugs/modalg_6/bug25908 b/tests/bugs/modalg_6/bug25908
index c39131f..081f0db 100755
--- a/tests/bugs/modalg_6/bug25908
+++ b/tests/bugs/modalg_6/bug25908
@@ -20,15 +20,15 @@ compound vl v1l vnl vol vil result
 
 set nbshapes_expected "
 Number of shapes in shape
- VERTEX    : 103
- EDGE      : 52
+ VERTEX    : 59
+ EDGE      : 30
  WIRE      : 0
  FACE      : 0
  SHELL     : 0
  SOLID     : 0
  COMPSOLID : 0
  COMPOUND  : 1
- SHAPE     : 156
+ SHAPE     : 90
 "
 
 checknbshapes result -ref ${nbshapes_expected} -t -m "HLRToShape"
diff --git a/tests/bugs/modalg_6/bug26206 b/tests/bugs/modalg_6/bug26206
deleted file mode 100644
index 7d7cfe1..0000000
--- a/tests/bugs/modalg_6/bug26206
+++ /dev/null
@@ -1,26 +0,0 @@
-puts "================"
-puts "OCC26206"
-puts "================"
-puts ""
-#######################################################################
-# BRepClass_FaceClassifier returns TopAbs_OUT for internal point
-#######################################################################
-
-restore [locate_data_file bug26206_group_1.brep] a
-
-point p 0.012676794773312086 0.04799218752935417
-
-set info [b2dclassify a p 1e-05]
-
-if { [regexp "The point is IN shape" $info] == 1  } {
-    puts "OK: point is IN shape"
-} else {
-    puts "Error : point should be IN shape"
-}
-
-pcurve a
-
-#v2d2
-view 1 -2D-  728 20 400 400
-2dfit
-xwd ${imagedir}/${test_image}.png
diff --git a/tests/bugs/modalg_6/bug26953_3 b/tests/bugs/modalg_6/bug26953_3
index 7e3d975..a9e5a96 100644
--- a/tests/bugs/modalg_6/bug26953_3
+++ b/tests/bugs/modalg_6/bug26953_3
@@ -17,6 +17,6 @@ baddtools b2
 bfillds
 bbop result 0
 
-checkprops result -s 40.7804
+checkprops result -s 40.9086
 
 checkview -display result -2d -path ${imagedir}/${test_image}.png
diff --git a/tests/bugs/modalg_6/bug27434 b/tests/bugs/modalg_6/bug27434
deleted file mode 100644
index efef2c5..0000000
--- a/tests/bugs/modalg_6/bug27434
+++ /dev/null
@@ -1,21 +0,0 @@
-puts "============"
-puts "OCC27434"
-puts "============"
-puts ""
-###############################
-## Wrong result of classification of the point in "infinity".
-###############################
-
-set BugNumber OCC27434
-
-restore [locate_data_file bug27434_ff.brep] ff
-point pp 3.5104958975622309 1.4497931574922160e+031
-
-set info [b2dclassify ff pp]
-set check [regexp "OUT" $info]
-
-if { ${check} == 1 } {
-    puts "OK ${BugNumber}"
-} else {
-    puts "Faulty ${BugNumber}"
-}
diff --git a/tests/bugs/modalg_6/bug28211_1 b/tests/bugs/modalg_6/bug28211_1
new file mode 100644
index 0000000..bba45fb
--- /dev/null
+++ b/tests/bugs/modalg_6/bug28211_1
@@ -0,0 +1,25 @@
+puts "========"
+puts "OCC28211"
+puts "========"
+puts ""
+#################################################
+# Modeling Algorithms - Boolean fuse operation produces incorrect result
+#################################################
+
+restore [locate_data_file bug28211_DDJ_BLD1_B_Pos3.brep] a
+
+explode a so
+bclearobjects
+bcleartools
+baddobjects a_1
+baddtools a_2
+bfillds
+
+# FUSE
+bbop result 1
+
+checkshape result
+checknbshapes result -solid 1 -shell 1
+checkprops result -v 13953.1 -s 4096.56
+
+checkview -display result -2d -path ${imagedir}/${test_image}.png
\ No newline at end of file
diff --git a/tests/bugs/modalg_6/bug28211_8 b/tests/bugs/modalg_6/bug28211_8
new file mode 100644
index 0000000..be7431d
--- /dev/null
+++ b/tests/bugs/modalg_6/bug28211_8
@@ -0,0 +1,24 @@
+puts "========"
+puts "OCC28211"
+puts "========"
+puts ""
+#################################################
+# Modeling Algorithms - Boolean fuse operation produces incorrect result
+#################################################
+
+restore [locate_data_file bug28211_MHX_VKT_WS_Pos3_source.brep] s
+restore [locate_data_file bug28211_MHX_VKT_WS_Pos3_tool.brep] t
+
+explode s f
+explode t f
+
+bnondestructive 1
+
+# Before the fix, exception in bsection algo was thrown.
+bsection r s_91 t_4
+
+bcut result s t
+
+checknbshapes result -solid 4 -shell 4 -face 105 -wire 105
+
+checkview -display result -2d -path ${imagedir}/${test_image}.png
\ No newline at end of file
diff --git a/tests/bugs/modalg_6/bug28800 b/tests/bugs/modalg_6/bug28800
new file mode 100644
index 0000000..6db6ffb
--- /dev/null
+++ b/tests/bugs/modalg_6/bug28800
@@ -0,0 +1,15 @@
+puts "============"
+puts "OCC28800"
+puts "============"
+puts ""
+###############################
+## The compound of two faces is incorrectly detected as self-interfered
+###############################
+
+restore [locate_data_file bug28800_faces.brep] result
+set bcheck [bopcheck result]
+if {![regexp {This shape seems to be OK.} $bcheck]} {
+    puts "Error: bopcheck failed"
+}
+
+checkview -display result -2d -path ${imagedir}/${test_image}.png
diff --git a/tests/bugs/modalg_7/bug23667 b/tests/bugs/modalg_7/bug23667
index e62c5b9..3425b94 100644
--- a/tests/bugs/modalg_7/bug23667
+++ b/tests/bugs/modalg_7/bug23667
@@ -1,3 +1,5 @@
+puts "REQUIRED All: Faulty shapes in variables faulty_1 to faulty_"
+
 puts "================"
 puts "OCC23667"
 puts "================"
diff --git a/tests/bugs/modalg_7/bug26842_1 b/tests/bugs/modalg_7/bug26842_1
index bfed223..d234b39 100644
--- a/tests/bugs/modalg_7/bug26842_1
+++ b/tests/bugs/modalg_7/bug26842_1
@@ -17,4 +17,11 @@ checksection result
 checknbshapes result -vertex 2 -edge 1
 checkprops result -l 1765.01
 
-checkview -display result -2d -path ${imagedir}/${test_image}.png
+smallview
+don result
+fit
+clear
+display s1
+display result
+
+checkview -screenshot -2d -path ${imagedir}/${test_image}.png
diff --git a/tests/bugs/modalg_7/bug26842_2 b/tests/bugs/modalg_7/bug26842_2
index 5d0178f..634f374 100644
--- a/tests/bugs/modalg_7/bug26842_2
+++ b/tests/bugs/modalg_7/bug26842_2
@@ -10,6 +10,15 @@ puts ""
 # bopsection result does not contain any edges.
 ##################################################
 
+# The main problem is in classifier-algorithm.
+# The intersection curve is found but is rejected
+# by BOP-operation because some intermediate point
+# of this curve is classified as OUT. 
+# Good fix must create adecvate polygon for classification,
+# which will respect the pcurve of the face with some deflection
+# (see method BRepTopAdaptor_FClass2d::Init(...)).
+# Currently, this polygon is wrong. 
+
 restore [locate_data_file bug26842_s2.brep] s2
 restore [locate_data_file bug26842_plane.brep] plane
 
@@ -19,6 +28,13 @@ checkshape result
 checksection result
 
 checknbshapes result -vertex 2 -edge 1
-checkprops result -l 1765.01
+checkprops result -l 3941.88
+
+smallview
+don result
+fit
+clear
+display s2
+display result
 
-checkview -display result -2d -path ${imagedir}/${test_image}.png
+checkview -screenshot -2d -path ${imagedir}/${test_image}.png
diff --git a/tests/bugs/modalg_7/bug28764 b/tests/bugs/modalg_7/bug28764
index 2609c4d..e066aec 100644
--- a/tests/bugs/modalg_7/bug28764
+++ b/tests/bugs/modalg_7/bug28764
@@ -20,5 +20,4 @@ set log [bopcurves f_1 f_2 -2d]
 checkview -screenshot -2d -path ${imagedir}/${test_image}.png
 
 regexp {Tolerance Reached=+([-0-9.+eE]+)} ${log} full Toler
-checkreal TolReached $Toler 4.60347250530349e-008 0.0 0.1
-
+checkreal TolReached $Toler 4.60347250530349e-008 1e-7 0.
diff --git a/tests/bugs/modalg_7/bug29204 b/tests/bugs/modalg_7/bug29204
index 8ce39b7..9c05115 100644
--- a/tests/bugs/modalg_7/bug29204
+++ b/tests/bugs/modalg_7/bug29204
@@ -19,7 +19,7 @@ checknbshapes result -solid 1 -shell 1 -face 28 -wire 28 -edge 64 -vertex 36 -sh
 
 set tolres [checkmaxtol result]
 
-if { ${tolres} > 0.001} {
+if { ${tolres} > 0.0011} {
    puts "Error: bad tolerance of result"
 }
 
diff --git a/tests/bugs/moddata_1/buc60609 b/tests/bugs/moddata_1/buc60609
deleted file mode 100755
index d3c1737..0000000
--- a/tests/bugs/moddata_1/buc60609
+++ /dev/null
@@ -1,21 +0,0 @@
-puts "================"
-puts "BUC60609"
-puts "================"
-
-restore [locate_data_file buc60609a.brep] a
-
-# two points will be classified
-point p1 0.14 5.1
-point p2 1.28 5.1
-
-if {![regexp "IN" [b2dclassify a p1]]} {
-  puts "Faulty BUC60609 first: $first is not right result. It should be INSIDE"
-} else {
-  puts "BUC60609 first OK:  It is INSIDE"
-}
-
-if {![regexp "IN" [b2dclassify a p2]]} {
-  puts "Faulty BUC60609 second: $second is not right result. It should be INSIDE"
-} else {
-  puts "BUC60609 second OK:  It is INSIDE"
-}
diff --git a/tests/bugs/moddata_1/bug22494 b/tests/bugs/moddata_1/bug22494
deleted file mode 100755
index bd56b21..0000000
--- a/tests/bugs/moddata_1/bug22494
+++ /dev/null
@@ -1,27 +0,0 @@
-puts "================"
-puts "OCC22494"
-puts "================"
-puts ""
-#######################################################################
-# BRepClass_FaceClassifier bug (ref SALOME issue 21185)
-#######################################################################
-
-set BugNumber OCC22494
-
-restore [locate_data_file bug22494_Pb_belogToGeom_FACE.brep] Face 
-
-point p -3.53254182396379145e-05 0.000877856930738714065
-
-set res [split [b2dclassify Face p] ]
-
-set ll [llength ${res}]
-if {${ll} < 4} {
-   puts "Bad format of bclassify draw-command; Faulty ${BugNumber}"
-} else {
-   if {[regexp {The point is ON shape} $res]} {
-      puts "OK ${BugNumber}"
-   } else {
-      puts "Faulty ${BugNumber}"
-   }
-}
-
diff --git a/tests/bugs/moddata_2/bug22746_3 b/tests/bugs/moddata_2/bug22746_3
index aa24416..75035c8 100755
--- a/tests/bugs/moddata_2/bug22746_3
+++ b/tests/bugs/moddata_2/bug22746_3
@@ -6,6 +6,8 @@ puts ""
 # Progress indicator in ShapeHealing
 ###########################################################################
 
+puts "TODO ?OCC28674 ALL: The area of result shape is"
+
 set BugNumber OCC22746
 
 set Min_ListLength 11
diff --git a/tests/bugs/moddata_2/bug23244 b/tests/bugs/moddata_2/bug23244
deleted file mode 100755
index 152ad72..0000000
--- a/tests/bugs/moddata_2/bug23244
+++ /dev/null
@@ -1,36 +0,0 @@
-puts "================"
-puts "OCC23244"
-puts "================"
-puts ""
-#######################################################################
-# Bug of BRepClass_FaceClassifier: it does not take into account the tolerance
-#######################################################################
-
-set BugNumber OCC23244
-
-restore [locate_data_file OCC23244-comp.brep] a
-
-explode a
-explode a_1
-
-smallview
-donly a_1_2 a_3
-fit
-
-mkpoint p3 a_3
-projponf a_1_2 p3
-point pp3 69.220445243320853 1216.6123701316949
-
-set result [split [b2dclassify a_1_2 pp3 1.e-5] ]
-
-set ll [llength ${result}]
-if {${ll} < 4} {
-   puts "Bad format of bclassify draw-command; Faulty ${BugNumber}"
-} else {
-   if { [regexp "ON" $result] == 1 } {
-      puts "OK ${BugNumber}"
-   } else {
-      puts "Faulty ${BugNumber}"
-   }
-}
-
diff --git a/tests/bugs/moddata_2/bug299 b/tests/bugs/moddata_2/bug299
index fca2b46..b1ef00c 100755
--- a/tests/bugs/moddata_2/bug299
+++ b/tests/bugs/moddata_2/bug299
@@ -1,5 +1,3 @@
-puts "TODO OCC11111 ALL: OCC299: Error 2"
-
 pload QAcommands
 
 puts "================"
@@ -17,7 +15,7 @@ set ll [llength ${info_result}]
 if { ${ll} < 4 } {
     puts "OCC299: Error 1"
 } else {
-    if { [regexp {IN} $info_result] } {
+    if { [regexp {OUT} $info_result] } {
 	puts "OCC299: OK"
     } else {
 	puts "OCC299: Error 2"
diff --git a/tests/bugs/moddata_2/bug377 b/tests/bugs/moddata_2/bug377
deleted file mode 100755
index 9f76dbe..0000000
--- a/tests/bugs/moddata_2/bug377
+++ /dev/null
@@ -1,22 +0,0 @@
-puts "TODO OCC11111 ALL: Error : OCC377"
-
-pload QAcommands
-
-puts "========"
-puts "OCC377"
-puts "BUC61056"
-puts "========"
-puts ""
-###################################################################
-##Incorrect behaviour of BRepTopAdapter_FClass2d. It cannot work with parametric representation 
-## of the first wire on  the face. It says that point (1.9812, -0.9557948)  is outside the contour  for
-##  forward wire and inside for reversed one if tolerance  is equal to 6.45    
-###################################################################
-
-set result_info [ OCC377 [locate_data_file OCC377.brep] 1.9812 -0.9557948 6.45 ]
-if { [ regexp {FAULTY} $result_info ]} {
-    puts "Error : OCC377"
-}
-
-checkview -display result -2d -path ${imagedir}/${test_image}.png
-
diff --git a/tests/bugs/moddata_2/bug538 b/tests/bugs/moddata_2/bug538
deleted file mode 100755
index 126b5dd..0000000
--- a/tests/bugs/moddata_2/bug538
+++ /dev/null
@@ -1,25 +0,0 @@
-puts "TODO OCC11111 ALL: Faulty OCC132"
-
-puts "================"
-puts "OCC538"
-puts "================"
-puts ""
-
-restore [locate_data_file OCC538.brep] Face 
-checkshape Face
-
-point p 0.2453959532714904 -1.246869357124329
-
-set res1 [b2dclassify Face p]
-set info_result [split ${res1}]
-
-set ll [llength ${info_result}]
-if {${ll} < 4} {
-    puts "Faulty OCC132"
-} else {
-    if {[regexp {IN} $info_result]} {
-	puts "OCC132 : OK"
-    } else {
-	puts "Faulty OCC132"
-    }
-}
diff --git a/tests/bugs/step/bug28256 b/tests/bugs/step/bug28256
index da63f8e..f752898 100644
--- a/tests/bugs/step/bug28256
+++ b/tests/bugs/step/bug28256
@@ -12,16 +12,16 @@ tpcompound result
 checkprops result -s 1.8e+101 
 
 set nbshapes_expected "
-Number of shapes in shape
+Number of shapes in result
  VERTEX    : 56881
  EDGE      : 85310
  WIRE      : 37795
- FACE      : 32992
+ FACE      : 32990
  SHELL     : 1318
  SOLID     : 1308
  COMPSOLID : 0
  COMPOUND  : 1
- SHAPE     : 215605
+ SHAPE     : 215603
 "
 checknbshapes result -ref ${nbshapes_expected} -t -m "importing file"
 checkview -display result -3d -path ${imagedir}/${test_image}.png
\ No newline at end of file
diff --git a/tests/de/iges_2/C5 b/tests/de/iges_2/C5
index 44924bd..d1509c9 100644
--- a/tests/de/iges_2/C5
+++ b/tests/de/iges_2/C5
@@ -1,6 +1,7 @@
 # !!!! This file is generated automatically, do not edit manually! See end script
 puts "TODO CR23096 ALL: TOLERANCE : Faulty" 
 puts "TODO CR23096 ALL: LABELS : Faulty" 
+puts "TODO CR28805 ALL: 1 differences with reference data found"
 
 
 set filename sim6049.igs
diff --git a/tests/de/iges_2/G7 b/tests/de/iges_2/G7
index c3e5599..a86eb95 100644
--- a/tests/de/iges_2/G7
+++ b/tests/de/iges_2/G7
@@ -1,9 +1,9 @@
 # !!!! This file is generated automatically, do not edit manually! See end script
 puts "TODO CR23096 ALL: CHECKSHAPE : Faulty" 
 puts "TODO CR23096 ALL: NBSHAPES : Faulty" 
-puts "TODO CR23096 ALL: STATSHAPE : Faulty" 
 puts "TODO CR23096 ALL: LABELS : Faulty" 
 puts "TODO CR23096 ALL: COLORS : Faulty" 
+puts "TODO CR28805 ALL: 3 differences with reference data found"
 
 
 set filename PRO18777-3.igs
diff --git a/tests/de/iges_2/H4 b/tests/de/iges_2/H4
index 8518edb..c5c30c3 100755
--- a/tests/de/iges_2/H4
+++ b/tests/de/iges_2/H4
@@ -3,6 +3,7 @@ puts "TODO CR23096 ALL: DATA : Faulty"
 puts "TODO CR23096 ALL: LABELS : Faulty" 
 puts "TODO CR23096 ALL: COLORS : Faulty" 
 puts "TODO CR23096 ALL: LAYERS : Faulty" 
+puts "TODO CR28805 ALL: 3 differences with reference data found"
 
 
 set filename UKI60028-2.igs
diff --git a/tests/de/iges_3/A1 b/tests/de/iges_3/A1
index 5a983e6..c331fa9 100644
--- a/tests/de/iges_3/A1
+++ b/tests/de/iges_3/A1
@@ -3,6 +3,7 @@ puts "TODO CR23096 ALL: NBSHAPES : Faulty"
 puts "TODO CR23096 ALL: STATSHAPE : Faulty" 
 puts "TODO CR23096 ALL: LABELS : Faulty" 
 puts "TODO CR23096 ALL: COLORS : Faulty" 
+puts "TODO CR28805 ALL: 3 differences with reference data found"
 
 
 set filename PUNZONE.igs
diff --git a/tests/de/step_3/E6 b/tests/de/step_3/E6
index 5ddfd3c..096ca74 100755
--- a/tests/de/step_3/E6
+++ b/tests/de/step_3/E6
@@ -3,6 +3,7 @@ puts "TODO CR23096 ALL:  Update of 3D-Parameters has failed"
 puts "TODO CR23096 ALL: CHECKSHAPE : Faulty" 
 puts "TODO CR23096 ALL: NBSHAPES : Faulty" 
 puts "TODO CR23096 ALL: STATSHAPE : Faulty" 
+puts "TODO CR28805 ALL: 2 differences with reference data found"
 
 
 set filename Z8M6SAT.stp
diff --git a/tests/heal/fix_shape/A1 b/tests/heal/fix_shape/A1
index 3c415fe..bd3cd9f 100644
--- a/tests/heal/fix_shape/A1
+++ b/tests/heal/fix_shape/A1
@@ -1,2 +1,11 @@
-puts "TODO OCC23127 ALL: Faulty shapes in variables faulty_1 to faulty_1"
+#puts "TODO OCC28863 ALL: Faulty shapes in variables faulty_1 to faulty_1"
+
+# Simple cylindrical face.
+# P-curve of the "top"-edge is geometrically
+# attached to the "bottom" one.
+# ShapeFix does not translate incorrect p-curve.
+# It increases the tolerance only in order to make the face be closed.
+# However, the current version of checkshape does not report about
+# self-intersecting.
+
 restore [locate_data_file aaa.rle] a
diff --git a/tests/heal/fix_shape/F7 b/tests/heal/fix_shape/F7
index 7e94fe7..b4f4979 100644
--- a/tests/heal/fix_shape/F7
+++ b/tests/heal/fix_shape/F7
@@ -1,2 +1,11 @@
-puts "TODO OCC23127 ALL: Faulty shapes in variables faulty_1 to faulty_1"
+#puts "TODO OCC28863 ALL: Faulty shapes in variables faulty_1 to faulty_1"
+
+# Simple cylindrical face.
+# P-curve of the "top"-edge is geometrically
+# attached to the "bottom" one.
+# ShapeFix does not translate incorrect p-curve.
+# It increases the tolerance only in order to make the face be closed.
+# However, the current version of checkshape does not report about
+# self-intersecting.
+
 restore [locate_data_file rrr.rle] a
diff --git a/tests/heal/surface_to_bspline/F2 b/tests/heal/surface_to_bspline/F2
index baec327..d00f9f3 100644
--- a/tests/heal/surface_to_bspline/F2
+++ b/tests/heal/surface_to_bspline/F2
@@ -1,3 +1,3 @@
-puts "TODO OCC23127 ALL: Faulty shapes in variables faulty_1 to faulty_2"
+puts "TODO OCC23127 ALL: Faulty shapes in variables faulty_1 to faulty_1"
 
 restore [locate_data_file rrr.rle] a
diff --git a/tests/lowalgos/classifier/buc60609 b/tests/lowalgos/classifier/buc60609
new file mode 100644
index 0000000..d3c1737
--- /dev/null
+++ b/tests/lowalgos/classifier/buc60609
@@ -0,0 +1,21 @@
+puts "================"
+puts "BUC60609"
+puts "================"
+
+restore [locate_data_file buc60609a.brep] a
+
+# two points will be classified
+point p1 0.14 5.1
+point p2 1.28 5.1
+
+if {![regexp "IN" [b2dclassify a p1]]} {
+  puts "Faulty BUC60609 first: $first is not right result. It should be INSIDE"
+} else {
+  puts "BUC60609 first OK:  It is INSIDE"
+}
+
+if {![regexp "IN" [b2dclassify a p2]]} {
+  puts "Faulty BUC60609 second: $second is not right result. It should be INSIDE"
+} else {
+  puts "BUC60609 second OK:  It is INSIDE"
+}
diff --git a/tests/lowalgos/classifier/bug22494 b/tests/lowalgos/classifier/bug22494
new file mode 100644
index 0000000..de0bf2b
--- /dev/null
+++ b/tests/lowalgos/classifier/bug22494
@@ -0,0 +1,26 @@
+puts "================"
+puts "OCC22494"
+puts "================"
+puts ""
+#######################################################################
+# BRepClass_FaceClassifier bug (ref SALOME issue 21185)
+#######################################################################
+
+set BugNumber OCC22494
+
+restore [locate_data_file bug22494_Pb_belogToGeom_FACE.brep] Face 
+
+point p -3.53254182396379145e-05 0.000877856930738714065
+
+set res [split [b2dclassify Face p] ]
+
+set ll [llength ${res}]
+if {${ll} < 4} {
+   puts "Bad format of bclassify draw-command; Faulty ${BugNumber}"
+} else {
+   if {[regexp {The point is ON shape} $res]} {
+      puts "OK ${BugNumber}"
+   } else {
+      puts "Faulty ${BugNumber}"
+   }
+}
diff --git a/tests/lowalgos/classifier/bug23244 b/tests/lowalgos/classifier/bug23244
new file mode 100644
index 0000000..729163a
--- /dev/null
+++ b/tests/lowalgos/classifier/bug23244
@@ -0,0 +1,36 @@
+puts "================"
+puts "OCC23244"
+puts "================"
+puts ""
+#######################################################################
+# Bug of BRepClass_FaceClassifier: it does not take into account the tolerance
+#######################################################################
+
+set BugNumber OCC23244
+
+restore [locate_data_file OCC23244-comp.brep] a
+
+explode a
+explode a_1
+
+smallview
+donly a_1_2 a_3
+fit
+
+mkpoint p3 a_3
+projponf a_1_2 p3
+point pp3 69.220445243320853 1216.6123701316949
+
+set result [split [b2dclassify a_1_2 pp3 -t 1.e-5] ]
+
+set ll [llength ${result}]
+if {${ll} < 4} {
+   puts "Bad format of bclassify draw-command; Faulty ${BugNumber}"
+} else {
+   if { [regexp "ON" $result] == 1 } {
+      puts "OK ${BugNumber}"
+   } else {
+      puts "Faulty ${BugNumber}"
+   }
+}
+
diff --git a/tests/lowalgos/classifier/bug23341 b/tests/lowalgos/classifier/bug23341
new file mode 100644
index 0000000..c78461b
--- /dev/null
+++ b/tests/lowalgos/classifier/bug23341
@@ -0,0 +1,21 @@
+puts "================"
+puts "OCC23341"
+puts "================"
+puts ""
+#######################################################################
+# Wrong result done by 2D classifier algorithm for a point and a face
+#######################################################################
+
+set BugNumber OCC23341
+
+restore [locate_data_file bug23341_f1] f1
+restore [locate_data_file bug23341_p] p
+set info [b2dclassify f1 p]
+set check [regexp "OUT" $info]
+
+if { ${check} == 1 } {
+    puts "OK ${BugNumber}"
+} else {
+    puts "Faulty ${BugNumber}"
+}
+
diff --git a/tests/lowalgos/classifier/bug23777 b/tests/lowalgos/classifier/bug23777
new file mode 100644
index 0000000..f02473f
--- /dev/null
+++ b/tests/lowalgos/classifier/bug23777
@@ -0,0 +1,22 @@
+puts "================"
+puts "OCC23777"
+puts "================"
+puts ""
+#######################################################################
+# 2D-Classifier algorithm produces wrong results for a point and face.
+#######################################################################
+
+set BugNumber OCC23777
+
+restore [locate_data_file bug23777_b1.brep] b1
+
+point p2D 0.062260538576946696 249583.00418413401
+
+set info [b2dclassify b1 p2D]
+set check [regexp "IN" $info]
+
+if { ${check} == 1 } {
+    puts "OK ${BugNumber}"
+} else {
+    puts "Faulty ${BugNumber}"
+}
diff --git a/tests/lowalgos/classifier/bug23849_2 b/tests/lowalgos/classifier/bug23849_2
new file mode 100644
index 0000000..504542b
--- /dev/null
+++ b/tests/lowalgos/classifier/bug23849_2
@@ -0,0 +1,23 @@
+puts "================"
+puts "OCC23849"
+puts "================"
+puts ""
+#######################################################################
+# BOP regression
+#######################################################################
+
+set BugNumber OCC23849
+
+restore [locate_data_file bug23849_segment_1.brep] b1
+explode b1 f
+
+point p2D 4.1882396063720497 50.643343428894831
+
+set info [b2dclassify b1_1 p2D]
+set check [regexp "IN" $info]
+
+if { ${check} == 1 } {
+    puts "OK ${BugNumber}"
+} else {
+    puts "Faulty ${BugNumber}"
+}
diff --git a/tests/lowalgos/classifier/bug24422 b/tests/lowalgos/classifier/bug24422
new file mode 100644
index 0000000..d16fcfc
--- /dev/null
+++ b/tests/lowalgos/classifier/bug24422
@@ -0,0 +1,25 @@
+puts "================"
+puts "OCC24422"
+puts "================"
+puts ""
+#######################################################################
+# Wrong result done by FaceClassifier algorythm
+#######################################################################
+
+restore [locate_data_file bug24422_Compound.brep] b 
+explode b f
+copy b_1 f
+
+point p 115.945392440981 106 230.000108990528
+point p_proj 230.00010899052799 1925.9453924409811
+set info [b2dclassify f p_proj]
+
+if { [regexp "The point is OUT of shape" $info] != 1  } {
+    puts "Error : point should be ON shape"
+} else {
+    puts "OK: point is OUT of shape"
+}
+
+axo
+fit
+checkview -screenshot -2d -path ${imagedir}/${test_image}.png
diff --git a/tests/lowalgos/classifier/bug25969 b/tests/lowalgos/classifier/bug25969
new file mode 100644
index 0000000..4c190ff
--- /dev/null
+++ b/tests/lowalgos/classifier/bug25969
@@ -0,0 +1,37 @@
+puts "================"
+puts "CR25969"
+puts "================"
+puts ""
+###############################################
+## Wrong result obtained by 2d classifier algorithm.
+###############################################
+
+pload DCAF
+
+Open [locate_data_file bug25969_pal22851.cbf] D
+
+GetShape D 0:1:15:1:1:2 b1
+GetShape D 0:1:29:1:1:2 b2
+ 
+explode b1
+explode b2
+ 
+bop b1_2 b2_1
+bopcut r
+
+explode r f
+copy r_4 f
+pcurve f
+ 
+point p 12.658283198213592 21.045164979270297 
+ 
+set cls1 [b2dclassifx f p]
+if { [regexp {OUT} $cls1] } {
+    puts "Error : Wrong result of 2d classifier algorithm"
+} else {
+    puts "OK : Good result of 2d classifier algorithm"
+}
+
+smallview
+fit
+checkview -screenshot -2d -path ${imagedir}/${test_image}.png
diff --git a/tests/lowalgos/classifier/bug25969_std b/tests/lowalgos/classifier/bug25969_std
new file mode 100644
index 0000000..a672786
--- /dev/null
+++ b/tests/lowalgos/classifier/bug25969_std
@@ -0,0 +1,37 @@
+puts "================"
+puts "CR25969"
+puts "================"
+puts ""
+###############################################
+## Wrong result obtained by 2d classifier algorithm.
+###############################################
+
+pload DCAF
+
+Open [locate_data_file bug25969_pal22851.sgd] D
+
+GetShape D 0:1:15:1:1:2 b1
+GetShape D 0:1:29:1:1:2 b2
+ 
+explode b1
+explode b2
+ 
+bop b1_2 b2_1
+bopcut r
+
+explode r f
+copy r_4 f
+pcurve f
+ 
+point p 12.658283198213592 21.045164979270297 
+ 
+set cls1 [b2dclassifx f p]
+if { [regexp {OUT} $cls1] } {
+    puts "Error : Wrong result of 2d classifier algorithm"
+} else {
+    puts "OK : Good result of 2d classifier algorithm"
+}
+
+smallview
+fit
+set only_screen_axo 1
diff --git a/tests/lowalgos/classifier/bug26206 b/tests/lowalgos/classifier/bug26206
new file mode 100644
index 0000000..263226b
--- /dev/null
+++ b/tests/lowalgos/classifier/bug26206
@@ -0,0 +1,26 @@
+puts "================"
+puts "OCC26206"
+puts "================"
+puts ""
+#######################################################################
+# BRepClass_FaceClassifier returns TopAbs_OUT for internal point
+#######################################################################
+
+restore [locate_data_file bug26206_group_1.brep] a
+
+point p 0.012676794773312086 0.04799218752935417
+
+set info [b2dclassify a p -t 1e-05]
+
+if { [regexp "The point is IN shape" $info] == 1  } {
+    puts "OK: point is IN shape"
+} else {
+    puts "Error : point should be IN shape"
+}
+
+pcurve a
+
+#v2d2
+view 1 -2D-  728 20 400 400
+2dfit
+xwd ${imagedir}/${test_image}.png
diff --git a/tests/lowalgos/classifier/bug27434 b/tests/lowalgos/classifier/bug27434
new file mode 100644
index 0000000..efef2c5
--- /dev/null
+++ b/tests/lowalgos/classifier/bug27434
@@ -0,0 +1,21 @@
+puts "============"
+puts "OCC27434"
+puts "============"
+puts ""
+###############################
+## Wrong result of classification of the point in "infinity".
+###############################
+
+set BugNumber OCC27434
+
+restore [locate_data_file bug27434_ff.brep] ff
+point pp 3.5104958975622309 1.4497931574922160e+031
+
+set info [b2dclassify ff pp]
+set check [regexp "OUT" $info]
+
+if { ${check} == 1 } {
+    puts "OK ${BugNumber}"
+} else {
+    puts "Faulty ${BugNumber}"
+}
diff --git a/tests/lowalgos/classifier/bug28211_10 b/tests/lowalgos/classifier/bug28211_10
new file mode 100644
index 0000000..25df0a8
--- /dev/null
+++ b/tests/lowalgos/classifier/bug28211_10
@@ -0,0 +1,36 @@
+puts "========"
+puts "OCC28211"
+puts "========"
+puts ""
+#################################################
+# Modeling Algorithms - Boolean fuse operation produces incorrect result
+#################################################
+
+# We create new face, which is not-closed in 2D- and 3D-space.
+# The face contains only single edge (with FORWARD-orientation)
+# and single vertex, which covers the gap.
+# After that, point is classified, which is
+# out of the face UV-bounds.
+
+circle cc 0 0 0 0 0 1 100
+trim cc cc 0.0001 2*pi-0.0001
+vertex vv 100 0 0
+mkedge ee cc
+emptycopy ee ee
+settolerance vv 0.05
+copy vv vr
+orientation vr R
+add vv ee
+add vr ee
+wire ww ee
+mkplane result ww
+
+checkshape result
+
+point pp 100.002 0.0
+
+if { ![regexp {OUT} [ b2dclassify result pp ] ] } {
+    puts "Error : Wrong result of 2d classifier algorithm"
+} else {
+    puts "OK : Good result of 2d classifier algorithm"
+}
diff --git a/tests/lowalgos/classifier/bug28211_11 b/tests/lowalgos/classifier/bug28211_11
new file mode 100644
index 0000000..6c528be
--- /dev/null
+++ b/tests/lowalgos/classifier/bug28211_11
@@ -0,0 +1,37 @@
+puts "========"
+puts "OCC28211"
+puts "========"
+puts ""
+#################################################
+# Modeling Algorithms - Boolean fuse operation produces incorrect result
+#################################################
+
+# We create new face, which is not-closed in 2D- and 3D-space.
+# The face contains only single edge (with REVERSED-orientation)
+# and single vertex, which covers the gap.
+# After that, point is classified, which is
+# out of the face UV-bounds.
+
+circle cc 0 0 0 0 0 1 100
+trim cc cc 0.0001 2*pi-0.0001
+vertex vv 100 0 0
+mkedge ee cc
+emptycopy ee ee
+settolerance vv 0.05
+copy vv vr
+orientation vr R
+orientation ee R
+add vv ee
+add vr ee
+wire ww ee
+mkplane result ww
+
+checkshape result
+
+point pp 100.002 0.0
+
+if { ![regexp {OUT} [ b2dclassify result pp ] ] } {
+    puts "Error : Wrong result of 2d classifier algorithm"
+} else {
+    puts "OK : Good result of 2d classifier algorithm"
+}
diff --git a/tests/lowalgos/classifier/bug28211_12 b/tests/lowalgos/classifier/bug28211_12
new file mode 100644
index 0000000..789e24e
--- /dev/null
+++ b/tests/lowalgos/classifier/bug28211_12
@@ -0,0 +1,49 @@
+puts "========"
+puts "OCC28211"
+puts "========"
+puts ""
+#################################################
+# Modeling Algorithms - Boolean fuse operation produces incorrect result
+#################################################
+
+# The face contains two edges
+# connected by their two vertices.
+# More over, two edges are connected by shared vertices
+# from one side and (from other side) by vertices,
+# which are common with seam:
+#
+#                  *************************
+#                  *                       *
+#            seam  *                       *  seam
+#                  *  edge1         edge2  *
+#                  * ********    ********* *
+#                  V1        V2   V3       V4
+#
+#  V1 - vertex between edge1 and seam
+#  V4 - vertex between edge2 and seam
+
+
+
+restore [locate_data_file bug28211_halfclosed.brep] result
+
+nbshapes result
+
+point pp 0.50013085652508904 -1.4847823204826136
+
+if { ![regexp {OUT} [ b2dclassifx result pp ] ] } {
+    puts "Error : Wrong result of b2dclassifx algorithm"
+} else {
+    puts "OK : Good result of b2dclassifx algorithm"
+}
+
+if { ![regexp {OUT} [ b2dclassify result pp ] ] } {
+    puts "Error : Wrong result of b2dclassify algorithm"
+} else {
+    puts "OK : Good result of b2dclassify algorithm"
+}
+
+v2d
+pcurve result
+2dfit
+
+checkview -screenshot -2d -path ${imagedir}/${test_image}.png
diff --git a/tests/lowalgos/classifier/bug28211_13 b/tests/lowalgos/classifier/bug28211_13
new file mode 100644
index 0000000..8a85425
--- /dev/null
+++ b/tests/lowalgos/classifier/bug28211_13
@@ -0,0 +1,34 @@
+puts "========"
+puts "OCC28211"
+puts "========"
+puts ""
+#################################################
+# Modeling Algorithms - Boolean fuse operation produces incorrect result
+#################################################
+
+# The face is not closed. Moreover, it contains NOT-CLOSED edge,
+# which has only single vertex and is covered by it.
+
+restore [locate_data_file bug28211_wface.brep] result
+
+nbshapes result
+
+point pp 3.4250396753448720 -12.076599999999999
+
+if { ![regexp {OUT} [ b2dclassifx result pp ] ] } {
+    puts "Error : Wrong result of b2dclassifx algorithm"
+} else {
+    puts "OK : Good result of b2dclassifx algorithm"
+}
+
+if { ![regexp {OUT} [ b2dclassify result pp ] ] } {
+    puts "Error : Wrong result of b2dclassify algorithm"
+} else {
+    puts "OK : Good result of b2dclassify algorithm"
+}
+
+v2d
+pcurve result
+2dfit
+
+checkview -screenshot -2d -path ${imagedir}/${test_image}.png
diff --git a/tests/lowalgos/classifier/bug28211_14 b/tests/lowalgos/classifier/bug28211_14
new file mode 100644
index 0000000..5f69001
--- /dev/null
+++ b/tests/lowalgos/classifier/bug28211_14
@@ -0,0 +1,47 @@
+puts "========"
+puts "OCC28211"
+puts "========"
+puts ""
+#################################################
+# Modeling Algorithms - Boolean fuse operation produces incorrect result
+#################################################
+
+# We create new face, which is not-closed in 2D-space.
+# This gap is created between two 2D-representations
+# of seam-edges (it is known fact that seam-edge has
+# two p-curves on the face) and is covered by the tolerance
+# of the vertex, which is shared between two edges.
+# After that, point is classified, which is
+# out of the face UV-bounds.
+
+plane pl 0 0 0 0 0 1
+pcylinder cy pl 1 100
+explode cy f
+emptycopy result cy_1
+explode cy_1 e
+copy cy_1_1 e1
+copy cy_1_2 e2
+copy cy_1_2 e3
+orientation e2 F
+orientation e3 R
+wire ww e1 e2 e3
+add ww result
+
+explode result v
+settolerance result_2 10
+
+checkshape result
+
+point pp 3.5 -10
+
+if { ![regexp {OUT} [ b2dclassifx result pp ] ] } {
+    puts "Error : Wrong result of b2dclassifx algorithm"
+} else {
+    puts "OK : Good result of b2dclassifx algorithm"
+}
+
+if { ![regexp {OUT} [ b2dclassify result pp ] ] } {
+    puts "Error : Wrong result of b2dclassify algorithm"
+} else {
+    puts "OK : Good result of b2dclassify algorithm"
+}
diff --git a/tests/lowalgos/classifier/bug28211_15 b/tests/lowalgos/classifier/bug28211_15
new file mode 100644
index 0000000..965af7e
--- /dev/null
+++ b/tests/lowalgos/classifier/bug28211_15
@@ -0,0 +1,35 @@
+puts "========"
+puts "OCC28211"
+puts "========"
+puts ""
+#################################################
+# Modeling Algorithms - Boolean fuse operation produces incorrect result
+#################################################
+
+# The face is self-interfered but valid because
+# this region is covered by the vertex tolerance
+# Before the fix, IntTools_FClass2d returned incorrect result.
+
+binrestore [locate_data_file bug28211_preadb7.brep] result
+
+checkshape result
+
+point pp -0.25003275806782399 5.9730635985427503
+
+if { ![regexp {OUT} [ b2dclassifx result pp ] ] } {
+    puts "Error : Wrong result of 2d classifier algorithm"
+} else {
+    puts "OK : Good result of 2d classifier algorithm"
+}
+
+if { ![regexp {OUT} [ b2dclassify result pp ] ] } {
+    puts "Error : Wrong result of 2d classifier algorithm"
+} else {
+    puts "OK : Good result of 2d classifier algorithm"
+}
+
+v2d
+pcurve result
+2dfit
+
+checkview -screenshot -2d -path ${imagedir}/${test_image}.png
diff --git a/tests/lowalgos/classifier/bug28211_16 b/tests/lowalgos/classifier/bug28211_16
new file mode 100644
index 0000000..35ff15a
--- /dev/null
+++ b/tests/lowalgos/classifier/bug28211_16
@@ -0,0 +1,35 @@
+puts "========"
+puts "OCC28211"
+puts "========"
+puts ""
+#################################################
+# Modeling Algorithms - Boolean fuse operation produces incorrect result
+#################################################
+
+# The face seems to be valid. But classified point is near to 
+# the corner (in 2D-space). So, many classification rays are tangent to
+# the existing ones or "goes" through the vertex.
+
+binrestore [locate_data_file bug28211_goodface.brep] result
+
+checkshape result
+
+point pp 336.9868940694347 491.1361705159796
+
+if { ![regexp {OUT} [ b2dclassifx result pp ] ] } {
+    puts "Error : Wrong result of 2d classifier algorithm"
+} else {
+    puts "OK : Good result of 2d classifier algorithm"
+}
+
+if { ![regexp {OUT} [ b2dclassify result pp ] ] } {
+    puts "Error : Wrong result of 2d classifier algorithm"
+} else {
+    puts "OK : Good result of 2d classifier algorithm"
+}
+
+v2d
+pcurve result
+2dfit
+
+checkview -screenshot -2d -path ${imagedir}/${test_image}.png
diff --git a/tests/lowalgos/classifier/bug28211_17 b/tests/lowalgos/classifier/bug28211_17
new file mode 100644
index 0000000..b511dbb
--- /dev/null
+++ b/tests/lowalgos/classifier/bug28211_17
@@ -0,0 +1,29 @@
+puts "========"
+puts "OCC28211"
+puts "========"
+puts ""
+#################################################
+# Modeling Algorithms - Boolean fuse operation produces incorrect result
+#################################################
+
+# The face seems to be valid but quite big (in 2D-space).
+# So, (almost) all classification rays are almost
+# tangent to existing ones.
+
+binrestore [locate_data_file bug28211_bigface.brep] result
+
+checkshape result
+
+point pp -3.1415926535980878 -63835.740811028722
+
+if { ![regexp {OUT} [ b2dclassifx result pp ] ] } {
+    puts "Error : Wrong result of 2d classifier algorithm"
+} else {
+    puts "OK : Good result of 2d classifier algorithm"
+}
+
+if { ![regexp {OUT} [ b2dclassify result pp ] ] } {
+    puts "Error : Wrong result of 2d classifier algorithm"
+} else {
+    puts "OK : Good result of 2d classifier algorithm"
+}
diff --git a/tests/lowalgos/classifier/bug28211_18 b/tests/lowalgos/classifier/bug28211_18
new file mode 100644
index 0000000..da7e4f6
--- /dev/null
+++ b/tests/lowalgos/classifier/bug28211_18
@@ -0,0 +1,60 @@
+puts "========"
+puts "OCC28211"
+puts "========"
+puts ""
+#################################################
+# Modeling Algorithms - Boolean fuse operation produces incorrect result
+#################################################
+
+# The classified face is based on the sphere and seems to be valid.
+# As far as we know, the sphere is not periodic in V-direction.
+# However, its equation contains only periodic trigonometric
+# function of V (x=f1(U)*cos(V), y=f2(U)*cos(V), z=R*sin(V),
+# where f1(U) and f2(U) are some (periodic) functions with
+# argument U, R is the radius of the sphere). Therefore,
+# if we decline to limit V-range of the sphere in the traditional
+# boundaries [-pi/2; +pi/2] the sphere will be true periodic in V-direction.
+# So, despite taking the classified point pp too far from the face domain
+# (in V-direction) it will be "converted" to the valid 3D-point ON the
+# some edge of the classified face. As result, there is a danger
+# to return ON-status from the classification algorithm. However,
+# it must return OUT.
+
+binrestore [locate_data_file bug28211_sphereon.brep] result
+
+checkshape result
+
+set px pi
+set py -2*pi
+
+point pp $px $py
+
+mksurface ss result
+svalue ss $px $py xx yy zz
+vertex vv xx yy zz
+
+smallview 
+donly result vv
+fit
+
+checkview -screenshot -2d -path ${imagedir}/${test_image}_3d.png
+
+if { ![regexp {OUT} [ b2dclassifx result pp ] ] } {
+    puts "Error : Wrong result of 2d classifier algorithm"
+} else {
+    puts "OK : Good result of 2d classifier algorithm"
+}
+
+if { ![regexp {OUT} [ b2dclassify result pp ] ] } {
+    puts "Error : Wrong result of 2d classifier algorithm"
+} else {
+    puts "OK : Good result of 2d classifier algorithm"
+}
+
+v2d
+2dclear
+display pp
+pcurve result
+2dfit
+
+checkview -screenshot -2d -path ${imagedir}/${test_image}_2d.png
diff --git a/tests/lowalgos/classifier/bug28211_19 b/tests/lowalgos/classifier/bug28211_19
new file mode 100644
index 0000000..c4edc7b
--- /dev/null
+++ b/tests/lowalgos/classifier/bug28211_19
@@ -0,0 +1,39 @@
+puts "========"
+puts "OCC28211"
+puts "========"
+puts ""
+#################################################
+# Modeling Algorithms - Boolean fuse operation produces incorrect result
+#################################################
+
+# The tolerance for classification (Toler = 1.0e-4) is enough
+# for returning ON-status.
+# However, b2dclassifx returned wrong result before the fix.
+
+set Toler 1.0e-4
+
+binrestore [locate_data_file bug28211_forblentTBSC1.brep] result
+
+checkshape result
+
+point pp 0.0010616212616224041 -4.5622747218199273e-005
+
+if { ![regexp {ON} [ b2dclassifx result pp -t $Toler] ] } {
+    puts "Error : Wrong result of 2d classifier algorithm"
+} else {
+    puts "OK : Good result of 2d classifier algorithm"
+}
+
+if { ![regexp {ON} [ b2dclassify result pp -t $Toler] ] } {
+    puts "Error : Wrong result of 2d classifier algorithm"
+} else {
+    puts "OK : Good result of 2d classifier algorithm"
+}
+
+v2d
+2dclear
+display pp
+pcurve result
+2dfit
+
+checkview -screenshot -2d -path ${imagedir}/${test_image}_2d.png
diff --git a/tests/lowalgos/classifier/bug28211_2 b/tests/lowalgos/classifier/bug28211_2
new file mode 100644
index 0000000..e44412a
--- /dev/null
+++ b/tests/lowalgos/classifier/bug28211_2
@@ -0,0 +1,69 @@
+puts "========"
+puts "OCC28211"
+puts "========"
+puts ""
+#################################################
+# Modeling Algorithms - Boolean fuse operation produces incorrect result
+#################################################
+
+# We create new face, which is not-closed in 2D-space.
+# This gap is covered by the tolerance of the vertex
+# and this vertex is shared between two edges.
+# After that, point is classified, which is
+# out of the face UV-bounds.
+
+box b1 10 10 1
+copy b1 b2
+btranslate b2 -10 0 0
+sewing bb b1 b2
+
+explode bb f
+
+explode bb_3 v
+copy bb_3_2 v1
+copy bb_3_3 v2
+copy bb_3_4 v3
+settolerance v1 1.5
+
+explode bb_3 e
+emptycopy e1 bb_3_2
+emptycopy e2 bb_3_3
+emptycopy e3 bb_3_4
+
+add v1 e1
+copy v1 v1c
+orientation v1c R
+
+add v2 e1
+copy v2 v2c
+orientation v2c F
+
+add v2c e2
+add v3 e2
+copy v3 v3c
+orientation v3c F
+
+add v3c e3
+add v1c e3
+
+wire w1 e1 e2 e3
+
+buildfaces f1 bb_3 w1
+explode f1 f
+copy f1_1 result
+
+checkshape result
+
+point pp 0.5 10
+
+if { ![regexp {OUT} [ b2dclassifx result pp ] ] } {
+    puts "Error : Wrong result of b2dclassifx algorithm"
+} else {
+    puts "OK : Good result of b2dclassifx algorithm"
+}
+
+if { ![regexp {OUT} [ b2dclassify result pp ] ] } {
+    puts "Error : Wrong result of b2dclassify algorithm"
+} else {
+    puts "OK : Good result of b2dclassify algorithm"
+}
diff --git a/tests/lowalgos/classifier/bug28211_20 b/tests/lowalgos/classifier/bug28211_20
new file mode 100644
index 0000000..99a1e31
--- /dev/null
+++ b/tests/lowalgos/classifier/bug28211_20
@@ -0,0 +1,43 @@
+puts "========"
+puts "OCC28211"
+puts "========"
+puts ""
+#################################################
+# Modeling Algorithms - Boolean fuse operation produces incorrect result
+#################################################
+
+# Before the fix, "b2dclassify" returned ON-status but
+# b2dclassifx returned OUT. After the fix, both
+# commands will return ON.
+# More over, the face is invalid:
+# InvalidCurveOnSurface and InvalidSameParameterFlag.
+
+puts "REQUIRED All: Faulty shapes in variables faulty_1 to faulty_2"
+
+set Toler 1.0e-7
+
+binrestore [locate_data_file bug28211_forhlr25908.brep] result
+
+checkshape result
+
+point pp 0.38952064924606344 1.8145650971005813
+
+if { ![regexp {ON} [ b2dclassifx result pp -t $Toler] ] } {
+    puts "Error : Wrong result of 2d classifier algorithm"
+} else {
+    puts "OK : Good result of 2d classifier algorithm"
+}
+
+if { ![regexp {ON} [ b2dclassify result pp -t $Toler] ] } {
+    puts "Error : Wrong result of 2d classifier algorithm"
+} else {
+    puts "OK : Good result of 2d classifier algorithm"
+}
+
+v2d
+2dclear
+display pp
+pcurve result
+2dfit
+
+checkview -screenshot -2d -path ${imagedir}/${test_image}_2d.png
diff --git a/tests/lowalgos/classifier/bug28211_21 b/tests/lowalgos/classifier/bug28211_21
new file mode 100644
index 0000000..01f49c9
--- /dev/null
+++ b/tests/lowalgos/classifier/bug28211_21
@@ -0,0 +1,43 @@
+puts "========"
+puts "OCC28211"
+puts "========"
+puts ""
+#################################################
+# Modeling Algorithms - Boolean fuse operation produces incorrect result
+#################################################
+
+# Classified point is IN indeed. However, we should
+# use "discr"-command (for v2d) in order to see it.
+# As result, classifier (which is based
+# on internal polygon) can create not precise polygon
+# and consequently return OUT-status.
+
+binrestore [locate_data_file bug28211_sharpface.brep] result
+
+checkshape result
+
+point pp 0.00071766949562590554 0.00070359754473026115
+
+if { ![regexp {IN} [ b2dclassifx result pp] ] } {
+    puts "Error : Wrong result of 2d classifier algorithm"
+} else {
+    puts "OK : Good result of 2d classifier algorithm"
+}
+
+if { ![regexp {IN} [ b2dclassify result pp] ] } {
+    puts "Error : Wrong result of 2d classifier algorithm"
+} else {
+    puts "OK : Good result of 2d classifier algorithm"
+}
+
+v2d
+display pp
+point p1t 0.00057279468289550453 0.00048191679048087871
+point p2t 0.00086390560797472069 0.00077038810872647509
+2dfit
+2dclear
+discr 1000
+display pp
+pcurve result
+
+checkview -screenshot -2d -path ${imagedir}/${test_image}_2d.png
diff --git a/tests/lowalgos/classifier/bug28211_22 b/tests/lowalgos/classifier/bug28211_22
new file mode 100644
index 0000000..82cc06e
--- /dev/null
+++ b/tests/lowalgos/classifier/bug28211_22
@@ -0,0 +1,38 @@
+puts "========"
+puts "OCC28211"
+puts "========"
+puts ""
+#################################################
+# Modeling Algorithms - Boolean fuse operation produces incorrect result
+#################################################
+
+# The face is trivial (without any specialities).
+# The result of classification must be ON.
+
+set Toler 1.0e-7
+
+binrestore [locate_data_file bug28211_trivialface.brep] result
+
+checkshape result
+
+point pp 1.0000000000000000 0.00010995037190202700
+
+if { ![regexp {ON} [ b2dclassifx result pp -t $Toler] ] } {
+    puts "Error : Wrong result of 2d classifier algorithm"
+} else {
+    puts "OK : Good result of 2d classifier algorithm"
+}
+
+if { ![regexp {ON} [ b2dclassify result pp -t $Toler] ] } {
+    puts "Error : Wrong result of 2d classifier algorithm"
+} else {
+    puts "OK : Good result of 2d classifier algorithm"
+}
+
+v2d
+2dclear
+display pp
+pcurve result
+2dfit
+
+checkview -screenshot -2d -path ${imagedir}/${test_image}_2d.png
diff --git a/tests/lowalgos/classifier/bug28211_23 b/tests/lowalgos/classifier/bug28211_23
new file mode 100644
index 0000000..c32232d
--- /dev/null
+++ b/tests/lowalgos/classifier/bug28211_23
@@ -0,0 +1,30 @@
+puts "========"
+puts "OCC28211"
+puts "========"
+puts ""
+#################################################
+# Modeling Algorithms - Boolean fuse operation produces incorrect result
+#################################################
+
+# The face contains gaps. However, these gaps are between curves only.
+# All vertices are in the ends of correspond curves.
+# Therefore, algorithm based on BRep_Tool::UVPoints does not create
+# pseudo-edges.
+
+binrestore [locate_data_file bug28211_notpseudogaps.bin] result
+
+checkshape result
+
+if { ![regexp {not hole} [ ishole result  ] ] } {
+    puts "Error : Wrong result of 2d classifier algorithm"
+} else {
+    puts "OK : Good result of 2d classifier algorithm"
+}
+
+v2d
+2dclear
+display pp
+pcurve result
+2dfit
+
+checkview -screenshot -2d -path ${imagedir}/${test_image}_2d.png
diff --git a/tests/lowalgos/classifier/bug28211_24 b/tests/lowalgos/classifier/bug28211_24
new file mode 100644
index 0000000..6a2f738
--- /dev/null
+++ b/tests/lowalgos/classifier/bug28211_24
@@ -0,0 +1,41 @@
+puts "========"
+puts "OCC28211"
+puts "========"
+puts ""
+#################################################
+# Modeling Algorithms - Boolean fuse operation produces incorrect result
+#################################################
+
+# The source face is trivial, based on planar surface but is invalid
+# in terms of same-parameter criterion.
+# The classified point is near to the edge. Therefore,
+# there is a dangerous to return ON-status. However, result must be IN.
+
+set Toler 1.0e-7
+
+binrestore [locate_data_file bug28211_planarface.bin] a
+
+fixshape result a
+checkshape result
+
+point pp 29.999999147417434 1971.5029199015287
+
+if { ![regexp {IN} [ b2dclassifx result pp -t $Toler] ] } {
+  puts "Error : Wrong result of 2d classifier algorithm"
+} else {
+  puts "OK : Good result of 2d classifier algorithm"
+}
+
+if { ![regexp {IN} [ b2dclassify result pp -t $Toler] ] } {
+  puts "Error : Wrong result of 2d classifier algorithm"
+} else {
+  puts "OK : Good result of 2d classifier algorithm"
+}
+
+v2d
+2dclear
+display pp
+pcurve result
+2dfit
+
+checkview -screenshot -2d -path ${imagedir}/${test_image}_2d.png
diff --git a/tests/lowalgos/classifier/bug28211_25 b/tests/lowalgos/classifier/bug28211_25
new file mode 100644
index 0000000..21f5963
--- /dev/null
+++ b/tests/lowalgos/classifier/bug28211_25
@@ -0,0 +1,42 @@
+puts "========"
+puts "OCC28211"
+puts "========"
+puts ""
+#################################################
+# Modeling Algorithms - Boolean fuse operation produces incorrect result
+#################################################
+
+# Check of work of polygonal classifier (CSLib_Class2d) when
+# the classified ray (which is parallel X-axis) goes through
+# some vertex of polygon 
+
+set px -24.5
+set py 26.2784601955168
+
+polyline pl 0 0 0 0 20 0 20 50 0 30 30 0 50 60 0 70 0 0 0 0 0
+mkplane result pl
+checkshape result
+
+point pp $px $py
+
+v2d
+2dclear
+display pp
+pcurve result
+2dfit
+
+checkview -screenshot -2d -path ${imagedir}/${test_image}_2d.png
+
+bounds result_3 u1 u2
+2dcvalue result_3 u1 xx yy
+
+if { [expr abs([dval yy]-$py)] > 1.0e-9} {
+  puts "Error: the classified ray (which is parallel X-axis) must go through some vertex of polygon."
+}
+
+if { ![regexp {OUT} [ b2dclassifx result pp] ] } {
+  puts "Error : Wrong result of 2d classifier algorithm"
+} else {
+  puts "OK : Good result of 2d classifier algorithm"
+}
+
diff --git a/tests/lowalgos/classifier/bug28211_26 b/tests/lowalgos/classifier/bug28211_26
new file mode 100644
index 0000000..b165ca0
--- /dev/null
+++ b/tests/lowalgos/classifier/bug28211_26
@@ -0,0 +1,42 @@
+puts "========"
+puts "OCC28211"
+puts "========"
+puts ""
+#################################################
+# Modeling Algorithms - Boolean fuse operation produces incorrect result
+#################################################
+
+# Check of work of polygonal classifier (CSLib_Class2d) when
+# the classified ray (which is parallel X-axis) goes through
+# some vertex of polygon 
+
+set px -16.02
+set py 0.16052066682861
+
+polyline pl 0 0 0 30 10 0 50 30 0 100 30 0 100 -5 0 0 0 0
+mkplane result pl
+checkshape result
+
+point pp $px $py
+
+v2d
+2dclear
+display pp
+pcurve result
+2dfit
+
+checkview -screenshot -2d -path ${imagedir}/${test_image}_2d.png
+
+bounds result_2 u1 u2
+2dcvalue result_2 u1 xx yy
+
+if { [expr abs([dval yy]-$py)] > 1.0e-9} {
+  puts "Error: the classified ray (which is parallel X-axis) must go through some vertex of polygon."
+}
+
+if { ![regexp {IN} [ b2dclassifx result pp] ] } {
+  puts "Error : Wrong result of 2d classifier algorithm"
+} else {
+  puts "OK : Good result of 2d classifier algorithm"
+}
+
diff --git a/tests/lowalgos/classifier/bug28211_27 b/tests/lowalgos/classifier/bug28211_27
new file mode 100644
index 0000000..124fbfb
--- /dev/null
+++ b/tests/lowalgos/classifier/bug28211_27
@@ -0,0 +1,50 @@
+puts "========"
+puts "OCC28211"
+puts "========"
+puts ""
+#################################################
+# Modeling Algorithms - Boolean fuse operation produces incorrect result
+#################################################
+
+# Check of work of polygonal classifier (CSLib_Class2d).
+# Especially for this case, aNullTolV local variable
+# has been added to SLib_Class2d::InternalClass(...) method.
+
+plane pl 0 -130 0 0 -1 0 1 0 0
+circle cc2 0 -130 0 0 -1 0 1 0 0 1026.5
+circle cc1 0 -130 0 0 -1 0 1 0 0 1145
+mkedge ee1 cc1
+mkedge ee2 cc2
+orientation ee2 R
+whatis ee1
+whatis ee2
+wire w1 ee1
+wire w2 ee2
+mkface result pl
+add w1 result
+add w2 result
+
+nbshapes result
+checkshape result
+
+point pp 268.78892051126780 990.82048099294911
+
+if { ![regexp {IN} [ b2dclassifx result pp ] ] } {
+  puts "Error : Wrong result of 2d classifier algorithm"
+} else {
+  puts "OK : Good result of 2d classifier algorithm"
+}
+
+if { ![regexp {IN} [ b2dclassify result pp ] ] } {
+  puts "Error : Wrong result of 2d classifier algorithm"
+} else {
+  puts "OK : Good result of 2d classifier algorithm"
+}
+
+v2d
+2dclear
+display pp
+pcurve result
+2dfit
+
+checkview -screenshot -2d -path ${imagedir}/${test_image}_2d.png
\ No newline at end of file
diff --git a/tests/lowalgos/classifier/bug28211_28 b/tests/lowalgos/classifier/bug28211_28
new file mode 100644
index 0000000..b4c450b
--- /dev/null
+++ b/tests/lowalgos/classifier/bug28211_28
@@ -0,0 +1,37 @@
+puts "========"
+puts "OCC28211"
+puts "========"
+puts ""
+#################################################
+# Modeling Algorithms - Boolean fuse operation produces incorrect result
+#################################################
+
+# Check of work of polygonal classifier (CSLib_Class2d)
+# with the complex face.
+
+set Toler 1.0e-7
+
+binrestore [locate_data_file bug28211_complexface.bin] result
+checkshape result
+
+point pp -1.0880999999945753 3.7557000000000000
+
+if { ![regexp {IN} [ b2dclassifx result pp -t $Toler ] ] } {
+  puts "Error : Wrong result of 2d classifier algorithm"
+} else {
+  puts "OK : Good result of 2d classifier algorithm"
+}
+
+if { ![regexp {IN} [ b2dclassify result pp -t $Toler ] ] } {
+  puts "Error : Wrong result of 2d classifier algorithm"
+} else {
+  puts "OK : Good result of 2d classifier algorithm"
+}
+
+v2d
+2dclear
+display pp
+pcurve result
+2dfit
+
+checkview -screenshot -2d -path ${imagedir}/${test_image}_2d.png
\ No newline at end of file
diff --git a/tests/lowalgos/classifier/bug28211_29 b/tests/lowalgos/classifier/bug28211_29
new file mode 100644
index 0000000..ad96140
--- /dev/null
+++ b/tests/lowalgos/classifier/bug28211_29
@@ -0,0 +1,116 @@
+puts "========"
+puts "OCC28211"
+puts "========"
+puts ""
+#################################################
+# Modeling Algorithms - Boolean fuse operation produces incorrect result
+#################################################
+
+# Another example of geometricaly not-closed face.
+# Principial factor in this case is to forbid 
+# use of polygonal classifier. If it launches, wrong result
+# will be obtained.
+
+plane pl 0 0 0 0 0 1
+bsplinecurve cc1 1 2 -0.105299999999371 2 0.10530000000008 2 2.31688587861 0 0 1 2.31688587861 0.1755 0 1 
+bsplinecurve cc2 1 2 0 2 2.31531201105 2 0 0.27 0 1 2.31688587861 0.27 0 1 
+bsplinecurve cc3 1 2 -0.10530000000008 2 0.105299999999371 2 0 0 0 1 0 0.1755 0 1
+bsplinecurve cc4 1 2 0 2 2.31531201105 2 0 0 0 1 2.31688587861 0 0 1
+mkedge e1 cc1
+mkedge e2 cc2
+mkedge e3 cc3
+mkedge e4 cc4
+
+explode e1 v
+copy e1_1 v1
+copy e1_2 v2
+explode e2 v
+copy e2_1 v3
+explode e3 v
+copy e3_1 v4
+
+emptycopy e1 e1
+emptycopy e2 e2
+emptycopy e3 e3
+emptycopy e4 e4
+
+orientation e1 F
+orientation e2 R
+orientation e3 R
+orientation e4 F
+
+# ---
+orientation v1 F
+orientation v2 R
+settolerance v2 0.1
+add v1 e1
+add v2 e1
+
+checknbshapes e1 -vertex 2 -edge 1
+if { ![regexp {FORWARD} [whatis e1] full] } {
+  puts "Error in e1 creation!"
+}
+
+# ---
+copy v2 v2c
+orientation v2c F
+orientation v3 R
+settolerance v3 0.1
+add v2c e2
+add v3 e2
+
+checknbshapes e2 -vertex 2 -edge 1
+if { ![regexp {REVERSED} [whatis e2] full] } {
+  puts "Error in e2 creation!"
+}
+
+# --
+copy v3 v3c
+orientation v3c F
+orientation v4 R
+add v3c e3
+add v4 e3
+
+checknbshapes e3 -vertex 2 -edge 1
+if { ![regexp {REVERSED} [whatis e3] full] } {
+  puts "Error in e3 creation!"
+}
+
+# --
+copy v4 v4c
+copy v1 v1c
+orientation v4c F
+orientation v1c R
+add v4c e4
+add v1c e4
+
+checknbshapes e4 -vertex 2 -edge 1
+if { ![regexp {FORWARD} [whatis e4] full] } {
+  puts "Error in e4 creation!"
+}
+
+wire ww e1 e2 e3 e4
+checknbshapes ww -vertex 4 -edge 4 -wire 1
+
+
+mkface result pl ww
+checkshape result
+
+point pp 2.3154730167575126 0.21264669107436251
+
+v2d
+pcurve result
+2dfit
+checkview -screenshot -2d -path ${imagedir}/${test_image}.png
+
+if { ![regexp {IN} [ b2dclassifx result pp ] ] } {
+    puts "Error : Wrong result of 2d classifier algorithm"
+} else {
+    puts "OK : Good result of 2d classifier algorithm"
+}
+
+if { ![regexp {IN} [ b2dclassify result pp ] ] } {
+    puts "Error : Wrong result of 2d classifier algorithm"
+} else {
+    puts "OK : Good result of 2d classifier algorithm"
+}
diff --git a/tests/lowalgos/classifier/bug28211_3 b/tests/lowalgos/classifier/bug28211_3
new file mode 100644
index 0000000..c92d9f8
--- /dev/null
+++ b/tests/lowalgos/classifier/bug28211_3
@@ -0,0 +1,69 @@
+puts "========"
+puts "OCC28211"
+puts "========"
+puts ""
+#################################################
+# Modeling Algorithms - Boolean fuse operation produces incorrect result
+#################################################
+
+# We create new face, which is not-closed in 2D-space.
+# This gap is covered by the tolerance of the vertex
+# and this vertex is shared between two edges.
+# After that, point is classified, which is
+# out of the face UV-bounds.
+
+box b1 10 10 1
+copy b1 b2
+btranslate b2 -10 0 0
+sewing bb b1 b2
+
+explode bb f
+
+explode bb_3 v
+copy bb_3_1 v1
+copy bb_3_2 v2
+copy bb_3_3 v3
+settolerance v3 1.5
+
+explode bb_3 e
+emptycopy e1 bb_3_1
+emptycopy e2 bb_3_2
+emptycopy e3 bb_3_4
+
+add v1 e1
+copy v1 v1c
+orientation v1c F
+
+add v2 e1
+copy v2 v2c
+orientation v2c R
+
+add v1c e2
+add v3 e2
+copy v3 v3c
+orientation v3c F
+
+add v3c e3
+add v2c e3
+
+wire w1 e1 e2 e3
+
+buildfaces f1 bb_3 w1
+explode f1 f
+copy f1_1 result
+
+checkshape result
+
+point pp 0.5 -20
+
+if { ![regexp {OUT} [ b2dclassifx result pp ] ] } {
+    puts "Error : Wrong result of b2dclassifx algorithm"
+} else {
+    puts "OK : Good result of b2dclassifx algorithm"
+}
+
+if { ![regexp {OUT} [ b2dclassify result pp ] ] } {
+    puts "Error : Wrong result of b2dclassify algorithm"
+} else {
+    puts "OK : Good result of b2dclassify algorithm"
+}
diff --git a/tests/lowalgos/classifier/bug28211_30 b/tests/lowalgos/classifier/bug28211_30
new file mode 100644
index 0000000..0191e01
--- /dev/null
+++ b/tests/lowalgos/classifier/bug28211_30
@@ -0,0 +1,34 @@
+puts "========"
+puts "OCC28211"
+puts "========"
+puts ""
+#################################################
+# Modeling Algorithms - Boolean fuse operation produces incorrect result
+#################################################
+
+# Check of work of polygonal classifier (CSLib_Class2d).
+# The result must be ON.
+
+set px  1513.57217669793
+set py -10.1029426238323
+
+2dpolyline result 1513.57217669793 11.0973538037081 -1051.81650575747 6.73452567267988 -1051.8152777319 6.00321559118616 -1051.80401237154 -0.66964148152312 -1051.79153179272 -8.00754731710954 -1051.78462891576 -12.0435532938874 -1051.7792064627 -15.1970808363544 1513.60824796713 -10.1029426238323 1513.6062129155 -8.92173663981858 1513.60388800065 -7.56876388778882 1513.60082451782 -5.78147799036545 1513.59744872383 -3.80726865383441 1513.59384827412 -1.69716087791358 1513.590129038 0.486912960705931 1513.58640596764 2.67747973139385 1513.582793967 4.80689217261492 1513.57903892674 7.02554393157767 1513.57532192993 9.22774787864227 1513.57217669793 11.0973538037081
+
+
+set log [polyclassify -s -c $px $py -t 0.0256560053668387 0.0256560053668387 -p result ]
+
+if { ![regexp {ON} $log ] } {
+  puts "Error : Wrong result of 2d classifier algorithm"
+} else {
+  puts "OK : Good result of 2d classifier algorithm"
+}
+
+v2d
+2dclear
+point p1 1513.4 -10.2
+point p2 1513.6 -9.8
+2dfit
+point pntsrc $px $py
+donly result pntsrc
+
+checkview -screenshot -2d -path ${imagedir}/${test_image}_2d.png
\ No newline at end of file
diff --git a/tests/lowalgos/classifier/bug28211_31 b/tests/lowalgos/classifier/bug28211_31
new file mode 100644
index 0000000..8968ee6
--- /dev/null
+++ b/tests/lowalgos/classifier/bug28211_31
@@ -0,0 +1,38 @@
+puts "========"
+puts "OCC28211"
+puts "========"
+puts ""
+#################################################
+# Modeling Algorithms - Boolean fuse operation produces incorrect result
+#################################################
+
+# Check of correct definition of ON-status if 3D- and 2D-
+# curve of edge (which the source point is in) is significant
+# greater than the input tolerance for classifier.
+
+set Toler 1.0e-7
+
+restore [locate_data_file bug28211_fiton.brep] result
+checkshape result
+
+point pp 0.42782232233104311 1.0000000346609297
+
+if { ![regexp {ON} [ b2dclassifx result pp -t $Toler ] ] } {
+  puts "Error : Wrong result of 2d classifier algorithm"
+} else {
+  puts "OK : Good result of 2d classifier algorithm"
+}
+
+if { ![regexp {ON} [ b2dclassify result pp -t $Toler ] ] } {
+  puts "Error : Wrong result of 2d classifier algorithm"
+} else {
+  puts "OK : Good result of 2d classifier algorithm"
+}
+
+v2d
+2dclear
+display pp
+pcurve result
+2dfit
+
+checkview -screenshot -2d -path ${imagedir}/${test_image}_2d.png
\ No newline at end of file
diff --git a/tests/lowalgos/classifier/bug28211_32 b/tests/lowalgos/classifier/bug28211_32
new file mode 100644
index 0000000..267474e
--- /dev/null
+++ b/tests/lowalgos/classifier/bug28211_32
@@ -0,0 +1,61 @@
+puts "========"
+puts "OCC28211"
+puts "========"
+puts ""
+#################################################
+# Modeling Algorithms - Boolean fuse operation produces incorrect result
+#################################################
+
+# The classified face is based on the sphere and seems to be valid.
+# As far as we know, the sphere is not periodic in V-direction.
+# However, its equation contains only periodic trigonometric
+# function of V (x=f1(U)*cos(V), y=f2(U)*cos(V), z=R*sin(V),
+# where f1(U) and f2(U) are some (periodic) functions with
+# argument U, R is the radius of the sphere). Therefore,
+# if we decline to limit V-range of the sphere in the traditional
+# boundaries [-pi/2; +pi/2] the sphere will be true periodic in V-direction.
+# So, despite taking the classified point pp too far from the face domain
+# (in V-direction) it will be "converted" to the valid 3D-point ON the
+# some edge of the classified face. As result, there is a danger
+# to return ON-status from the classification algorithm. However,
+# it must return OUT.
+# Classified point is near to the sphere apex (in 3D-space)
+
+restore [locate_data_file bug28211_spherepole.brep] result
+
+checkshape result
+
+set px 3.14159265358979
+set py 1.57079634
+
+point pp $px $py
+
+mksurface ss result
+svalue ss $px $py xx yy zz
+vertex vv xx yy zz
+
+smallview 
+donly result vv
+fit
+
+checkview -screenshot -2d -path ${imagedir}/${test_image}_3d.png
+
+if { ![regexp {OUT} [ b2dclassifx result pp ] ] } {
+    puts "Error : Wrong result of 2d classifier algorithm"
+} else {
+    puts "OK : Good result of 2d classifier algorithm"
+}
+
+if { ![regexp {OUT} [ b2dclassify result pp ] ] } {
+    puts "Error : Wrong result of 2d classifier algorithm"
+} else {
+    puts "OK : Good result of 2d classifier algorithm"
+}
+
+v2d
+2dclear
+display pp
+pcurve result
+2dfit
+
+checkview -screenshot -2d -path ${imagedir}/${test_image}_2d.png
diff --git a/tests/lowalgos/classifier/bug28211_33 b/tests/lowalgos/classifier/bug28211_33
new file mode 100644
index 0000000..78f8785
--- /dev/null
+++ b/tests/lowalgos/classifier/bug28211_33
@@ -0,0 +1,50 @@
+puts "========"
+puts "OCC28211"
+puts "========"
+puts ""
+#################################################
+# Modeling Algorithms - Boolean fuse operation produces incorrect result
+#################################################
+
+# The classified face is based on the sphere and seems to be valid.
+# Classified point is near to the sphere apex.
+# So, result must be ON.
+
+restore [locate_data_file bug28211_spherepole.brep] result
+
+checkshape result
+
+set px 6.28318531
+set py 1.57079634
+
+point pp $px $py
+
+mksurface ss result
+svalue ss $px $py xx yy zz
+vertex vv xx yy zz
+
+smallview 
+donly result vv
+fit
+
+checkview -screenshot -2d -path ${imagedir}/${test_image}_3d.png
+
+if { ![regexp {ON} [ b2dclassifx result pp -t 1.0e-7 ] ] } {
+    puts "Error : Wrong result of 2d classifier algorithm"
+} else {
+    puts "OK : Good result of 2d classifier algorithm"
+}
+
+if { ![regexp {ON} [ b2dclassify result pp -t 1.0e-7 ] ] } {
+    puts "Error : Wrong result of 2d classifier algorithm"
+} else {
+    puts "OK : Good result of 2d classifier algorithm"
+}
+
+v2d
+2dclear
+display pp
+pcurve result
+2dfit
+
+checkview -screenshot -2d -path ${imagedir}/${test_image}_2d.png
diff --git a/tests/lowalgos/classifier/bug28211_34 b/tests/lowalgos/classifier/bug28211_34
new file mode 100644
index 0000000..843cf61
--- /dev/null
+++ b/tests/lowalgos/classifier/bug28211_34
@@ -0,0 +1,62 @@
+puts "========"
+puts "OCC28211"
+puts "========"
+puts ""
+#################################################
+# Modeling Algorithms - Boolean fuse operation produces incorrect result
+#################################################
+
+# The classified face is based on the sphere and seems to be valid.
+# As far as we know, the sphere is not periodic in V-direction.
+# However, its equation contains only periodic trigonometric
+# function of V (x=f1(U)*cos(V), y=f2(U)*cos(V), z=R*sin(V),
+# where f1(U) and f2(U) are some (periodic) functions with
+# argument U, R is the radius of the sphere). Therefore,
+# if we decline to limit V-range of the sphere in the traditional
+# boundaries [-pi/2; +pi/2] the sphere will be true periodic in V-direction.
+# So, despite taking the classified point pp too far from the face domain
+# (in V-direction) it will be "converted" to the valid 3D-point ON the
+# some edge of the classified face. As result, there is a danger
+# to return ON-status from the classification algorithm. However,
+# it must return OUT.
+# Moreover, the source face is based on the offset surface
+# (basis surface is sphere).
+
+restore [locate_data_file bug28211_sphereoffset.brep] result
+
+checkshape result
+
+set px pi
+set py -2.9878952687994853
+
+point pp $px $py
+
+mksurface ss result
+svalue ss $px $py xx yy zz
+vertex vv xx yy zz
+
+smallview 
+donly result vv
+fit
+
+checkview -screenshot -2d -path ${imagedir}/${test_image}_3d.png
+
+if { ![regexp {OUT} [ b2dclassifx result pp ] ] } {
+    puts "Error : Wrong result of 2d classifier algorithm"
+} else {
+    puts "OK : Good result of 2d classifier algorithm"
+}
+
+if { ![regexp {OUT} [ b2dclassify result pp ] ] } {
+    puts "Error : Wrong result of 2d classifier algorithm"
+} else {
+    puts "OK : Good result of 2d classifier algorithm"
+}
+
+v2d
+2dclear
+display pp
+pcurve result
+2dfit
+
+checkview -screenshot -2d -path ${imagedir}/${test_image}_2d.png
diff --git a/tests/lowalgos/classifier/bug28211_35 b/tests/lowalgos/classifier/bug28211_35
new file mode 100644
index 0000000..532d219
--- /dev/null
+++ b/tests/lowalgos/classifier/bug28211_35
@@ -0,0 +1,60 @@
+puts "========"
+puts "OCC28211"
+puts "========"
+puts ""
+#################################################
+# Modeling Algorithms - Boolean fuse operation produces incorrect result
+#################################################
+
+# The classified face is based on the sphere and seems to be valid.
+# As far as we know, the sphere is not periodic in V-direction.
+# However, its equation contains only periodic trigonometric
+# function of V (x=f1(U)*cos(V), y=f2(U)*cos(V), z=R*sin(V),
+# where f1(U) and f2(U) are some (periodic) functions with
+# argument U, R is the radius of the sphere). Therefore,
+# if we decline to limit V-range of the sphere in the traditional
+# boundaries [-pi/2; +pi/2] the sphere will be true periodic in V-direction.
+# So, despite taking the classified point pp too far from the face domain
+# (in V-direction) it will be "converted" to the valid 3D-point ON the
+# some edge of the classified face. As result, there is a danger
+# to return ON-status from the classification algorithm. However,
+# it must return OUT.
+
+restore [locate_data_file bug28211_sphseam.brep] result
+
+checkshape result
+
+set px pi
+set py -2.9878952687994853
+
+point pp $px $py
+
+mksurface ss result
+svalue ss $px $py xx yy zz
+vertex vv xx yy zz
+
+smallview 
+donly result vv
+fit
+
+checkview -screenshot -2d -path ${imagedir}/${test_image}_3d.png
+
+if { ![regexp {OUT} [ b2dclassifx result pp ] ] } {
+    puts "Error : Wrong result of 2d classifier algorithm"
+} else {
+    puts "OK : Good result of 2d classifier algorithm"
+}
+
+if { ![regexp {OUT} [ b2dclassify result pp ] ] } {
+    puts "Error : Wrong result of 2d classifier algorithm"
+} else {
+    puts "OK : Good result of 2d classifier algorithm"
+}
+
+v2d
+2dclear
+display pp
+pcurve result
+2dfit
+
+checkview -screenshot -2d -path ${imagedir}/${test_image}_2d.png
diff --git a/tests/lowalgos/classifier/bug28211_36 b/tests/lowalgos/classifier/bug28211_36
new file mode 100644
index 0000000..b846d8d
--- /dev/null
+++ b/tests/lowalgos/classifier/bug28211_36
@@ -0,0 +1,54 @@
+puts "========"
+puts "OCC28211"
+puts "========"
+puts ""
+#################################################
+# Modeling Algorithms - Boolean fuse operation produces incorrect result
+#################################################
+
+# The classified face is based on surface of revolution (based on ellipse).
+# Such surface can be considered as periodic (see pictures).
+# So, despite taking the classified point pp too far from the face domain
+# (in V-direction) it will be "converted" to the valid 3D-point ON the
+# some edge of the classified face. As result, there is a danger
+# to return ON-status from the classification algorithm. However,
+# it must return OUT.
+
+restore [locate_data_file bug28211_revfaceon.brep] result
+
+checkshape result
+
+set px pi
+set py -0.1
+
+point pp $px $py
+
+mksurface ss result
+svalue ss $px $py xx yy zz
+vertex vv xx yy zz
+
+smallview 
+donly result vv
+fit
+
+checkview -screenshot -2d -path ${imagedir}/${test_image}_3d.png
+
+if { ![regexp {OUT} [ b2dclassifx result pp ] ] } {
+    puts "Error : Wrong result of 2d classifier algorithm"
+} else {
+    puts "OK : Good result of 2d classifier algorithm"
+}
+
+if { ![regexp {OUT} [ b2dclassify result pp ] ] } {
+    puts "Error : Wrong result of 2d classifier algorithm"
+} else {
+    puts "OK : Good result of 2d classifier algorithm"
+}
+
+v2d
+2dclear
+display pp
+pcurve result
+2dfit
+
+checkview -screenshot -2d -path ${imagedir}/${test_image}_2d.png
diff --git a/tests/lowalgos/classifier/bug28211_37 b/tests/lowalgos/classifier/bug28211_37
new file mode 100644
index 0000000..77821be
--- /dev/null
+++ b/tests/lowalgos/classifier/bug28211_37
@@ -0,0 +1,50 @@
+puts "========"
+puts "OCC28211"
+puts "========"
+puts ""
+#################################################
+# Modeling Algorithms - Boolean fuse operation produces incorrect result
+#################################################
+
+# This case differs from bug28211_34 by that the fase is
+# based on trimmed surface.
+# So, result must be OUT (as in bug28211_34 test case).
+
+restore [locate_data_file bug28211_spheretrpole.brep] result
+
+checkshape result
+
+set px 6.28318531
+set py 1.57079634
+
+point pp $px $py
+
+mksurface ss result
+svalue ss $px $py xx yy zz
+vertex vv xx yy zz
+
+smallview 
+donly result vv
+fit
+
+checkview -screenshot -2d -path ${imagedir}/${test_image}_3d.png
+
+if { ![regexp {OUT} [ b2dclassifx result pp -t 1.0e-7 ] ] } {
+    puts "Error : Wrong result of 2d classifier algorithm"
+} else {
+    puts "OK : Good result of 2d classifier algorithm"
+}
+
+if { ![regexp {OUT} [ b2dclassify result pp -t 1.0e-7 ] ] } {
+    puts "Error : Wrong result of 2d classifier algorithm"
+} else {
+    puts "OK : Good result of 2d classifier algorithm"
+}
+
+v2d
+2dclear
+display pp
+pcurve result
+2dfit
+
+checkview -screenshot -2d -path ${imagedir}/${test_image}_2d.png
diff --git a/tests/lowalgos/classifier/bug28211_38 b/tests/lowalgos/classifier/bug28211_38
new file mode 100644
index 0000000..21a5944
--- /dev/null
+++ b/tests/lowalgos/classifier/bug28211_38
@@ -0,0 +1,50 @@
+puts "========"
+puts "OCC28211"
+puts "========"
+puts ""
+#################################################
+# Modeling Algorithms - Boolean fuse operation produces incorrect result
+#################################################
+
+# This case differs from bug28211_33 by that the fase is
+# based on trimmed surface.
+# So, result must be ON (as in bug28211_33 test case).
+
+restore [locate_data_file bug28211_spheretrpole.brep] result
+
+checkshape result
+
+set px 3.14159266
+set py 1.57079634
+
+point pp $px $py
+
+mksurface ss result
+svalue ss $px $py xx yy zz
+vertex vv xx yy zz
+
+smallview 
+donly result vv
+fit
+
+checkview -screenshot -2d -path ${imagedir}/${test_image}_3d.png
+
+if { ![regexp {ON} [ b2dclassifx result pp -t 1.0e-7 ] ] } {
+    puts "Error : Wrong result of 2d classifier algorithm"
+} else {
+    puts "OK : Good result of 2d classifier algorithm"
+}
+
+if { ![regexp {ON} [ b2dclassify result pp -t 1.0e-7 ] ] } {
+    puts "Error : Wrong result of 2d classifier algorithm"
+} else {
+    puts "OK : Good result of 2d classifier algorithm"
+}
+
+v2d
+2dclear
+display pp
+pcurve result
+2dfit
+
+checkview -screenshot -2d -path ${imagedir}/${test_image}_2d.png
diff --git a/tests/lowalgos/classifier/bug28211_39 b/tests/lowalgos/classifier/bug28211_39
new file mode 100644
index 0000000..6daacd9
--- /dev/null
+++ b/tests/lowalgos/classifier/bug28211_39
@@ -0,0 +1,62 @@
+puts "========"
+puts "OCC28211"
+puts "========"
+puts ""
+#################################################
+# Modeling Algorithms - Boolean fuse operation produces incorrect result
+#################################################
+
+# The classified face is based on the sphere and seems to be valid.
+# As far as we know, the sphere is not periodic in V-direction.
+# However, its equation contains only periodic trigonometric
+# function of V (x=f1(U)*cos(V), y=f2(U)*cos(V), z=R*sin(V),
+# where f1(U) and f2(U) are some (periodic) functions with
+# argument U, R is the radius of the sphere). Therefore,
+# if we decline to limit V-range of the sphere in the traditional
+# boundaries [-pi/2; +pi/2] the sphere will be true periodic in V-direction.
+# So, despite taking the classified point pp too far from the face domain
+# (in V-direction) it will be "converted" to the valid 3D-point ON the
+# some edge of the classified face. As result, there is a danger
+# to return ON-status from the classification algorithm. However,
+# it must return OUT.
+# Moreover, the source face is based on the offset surface
+# (basis surface is sphere).
+
+restore [locate_data_file bug28211_sphereoffset.brep] result
+
+checkshape result
+
+set px 0
+set py [dval 2*pi]
+
+point pp $px $py
+
+mksurface ss result
+svalue ss $px $py xx yy zz
+vertex vv xx yy zz
+
+smallview 
+donly result vv
+fit
+
+checkview -screenshot -2d -path ${imagedir}/${test_image}_3d.png
+
+if { ![regexp {OUT} [ b2dclassifx result pp ] ] } {
+    puts "Error : Wrong result of 2d classifier algorithm"
+} else {
+    puts "OK : Good result of 2d classifier algorithm"
+}
+
+if { ![regexp {OUT} [ b2dclassify result pp ] ] } {
+    puts "Error : Wrong result of 2d classifier algorithm"
+} else {
+    puts "OK : Good result of 2d classifier algorithm"
+}
+
+v2d
+2dclear
+display pp
+pcurve result
+2dfit
+
+checkview -screenshot -2d -path ${imagedir}/${test_image}_2d.png
diff --git a/tests/lowalgos/classifier/bug28211_4 b/tests/lowalgos/classifier/bug28211_4
new file mode 100644
index 0000000..51ca604
--- /dev/null
+++ b/tests/lowalgos/classifier/bug28211_4
@@ -0,0 +1,69 @@
+puts "========"
+puts "OCC28211"
+puts "========"
+puts ""
+#################################################
+# Modeling Algorithms - Boolean fuse operation produces incorrect result
+#################################################
+
+# We create new face, which is not-closed in 2D-space.
+# This gap is covered by the tolerance of the vertex
+# and this vertex is shared between two edges.
+# After that, point is classified, which is
+# out of the face UV-bounds.
+
+box b1 10 10 1
+copy b1 b2
+btranslate b2 -10 0 0
+sewing bb b1 b2
+
+explode bb f
+
+explode bb_7 v
+copy bb_7_2 v1
+copy bb_7_3 v2
+copy bb_7_4 v3
+settolerance v1 1.5
+
+explode bb_7 e
+emptycopy e1 bb_7_2
+emptycopy e2 bb_7_3
+emptycopy e3 bb_7_4
+
+add v1 e1
+copy v1 v1c
+orientation v1c F
+
+add v2 e1
+copy v2 v2c
+orientation v2c R
+
+add v2c e2
+add v3 e2
+copy v3 v3c
+orientation v3c R
+
+add v3c e3
+add v1c e3
+
+wire w1 e1 e2 e3
+
+buildfaces f1 bb_7 w1
+explode f1 f
+copy f1_1 result
+
+checkshape result
+
+point pp 0.5 10
+
+if { ![regexp {OUT} [ b2dclassifx result pp ] ] } {
+    puts "Error : Wrong result of b2dclassifx algorithm"
+} else {
+    puts "OK : Good result of b2dclassifx algorithm"
+}
+
+if { ![regexp {OUT} [ b2dclassify result pp ] ] } {
+    puts "Error : Wrong result of b2dclassify algorithm"
+} else {
+    puts "OK : Good result of b2dclassify algorithm"
+}
diff --git a/tests/lowalgos/classifier/bug28211_40 b/tests/lowalgos/classifier/bug28211_40
new file mode 100644
index 0000000..bd04244
--- /dev/null
+++ b/tests/lowalgos/classifier/bug28211_40
@@ -0,0 +1,49 @@
+puts "========"
+puts "OCC28211"
+puts "========"
+puts ""
+#################################################
+# Modeling Algorithms - Boolean fuse operation produces incorrect result
+#################################################
+
+# The classified face is based on the sphere and seems to be valid.
+# Check "-na" option for "b2dclassifx"-DRAW-command.
+
+pcylinder rr 3 5
+explode rr f
+copy rr_1 result
+
+point p1 0 2
+point p2 -2*pi 2
+
+if { ![regexp {ON} [ b2dclassifx result p1 ] ] } {
+    puts "Error : Wrong result of 2d classifier algorithm"
+} else {
+    puts "OK : Good result of 2d classifier algorithm"
+}
+
+if { ![regexp {ON} [ b2dclassifx result p1 -na ] ] } {
+    puts "Error : Wrong result of 2d classifier algorithm"
+} else {
+    puts "OK : Good result of 2d classifier algorithm"
+}
+
+if { ![regexp {ON} [ b2dclassifx result p2 ] ] } {
+    puts "Error : Wrong result of 2d classifier algorithm"
+} else {
+    puts "OK : Good result of 2d classifier algorithm"
+}
+
+if { ![regexp {OUT} [ b2dclassify result p2 -na ] ] } {
+    puts "Error : Wrong result of 2d classifier algorithm"
+} else {
+    puts "OK : Good result of 2d classifier algorithm"
+}
+
+v2d
+2dclear
+display p1 p2
+pcurve result
+2dfit
+
+checkview -screenshot -2d -path ${imagedir}/${test_image}_2d.png
diff --git a/tests/lowalgos/classifier/bug28211_5 b/tests/lowalgos/classifier/bug28211_5
new file mode 100644
index 0000000..7244b3d
--- /dev/null
+++ b/tests/lowalgos/classifier/bug28211_5
@@ -0,0 +1,69 @@
+puts "========"
+puts "OCC28211"
+puts "========"
+puts ""
+#################################################
+# Modeling Algorithms - Boolean fuse operation produces incorrect result
+#################################################
+
+# We create new face, which is not-closed in 2D-space.
+# This gap is covered by the tolerance of the vertex
+# and this vertex is shared between two edges.
+# After that, point is classified, which is
+# out of the face UV-bounds.
+
+box b1 10 10 1
+copy b1 b2
+btranslate b2 -10 0 0
+sewing bb b1 b2
+
+explode bb f
+
+explode bb_7 v
+copy bb_7_1 v1
+copy bb_7_2 v2
+copy bb_7_3 v3
+settolerance v3 1.5
+
+explode bb_7 e
+emptycopy e1 bb_7_1
+emptycopy e2 bb_7_2
+emptycopy e3 bb_7_4
+
+add v1 e1
+copy v1 v1c
+orientation v1c R
+
+add v2 e1
+copy v2 v2c
+orientation v2c F
+
+add v1c e2
+add v3 e2
+copy v3 v3c
+orientation v3c R
+
+add v3c e3
+add v2c e3
+
+wire w1 e1 e2 e3
+
+buildfaces f1 bb_7 w1
+explode f1 f
+copy f1_1 result
+
+checkshape result
+
+point pp 0.5 -20
+
+if { ![regexp {OUT} [ b2dclassifx result pp ] ] } {
+    puts "Error : Wrong result of b2dclassifx algorithm"
+} else {
+    puts "OK : Good result of b2dclassifx algorithm"
+}
+
+if { ![regexp {OUT} [ b2dclassify result pp ] ] } {
+    puts "Error : Wrong result of b2dclassify algorithm"
+} else {
+    puts "OK : Good result of b2dclassify algorithm"
+}
diff --git a/tests/lowalgos/classifier/bug28211_6 b/tests/lowalgos/classifier/bug28211_6
new file mode 100644
index 0000000..f6efd53
--- /dev/null
+++ b/tests/lowalgos/classifier/bug28211_6
@@ -0,0 +1,36 @@
+puts "========"
+puts "OCC28211"
+puts "========"
+puts ""
+#################################################
+# Modeling Algorithms - Boolean fuse operation produces incorrect result
+#################################################
+
+# Classification the point on periodic face.
+
+restore [locate_data_file CTO904_pro14942a.rle] a 
+explode a f
+
+copy a_1 result
+
+checkshape result
+
+point pp 3.1415926535897949 1.3545376643853366
+
+if { ![regexp {OUT} [ b2dclassifx result pp ] ] } {
+    puts "Error : Wrong result of b2dclassifx algorithm"
+} else {
+    puts "OK : Good result of b2dclassifx algorithm"
+}
+
+if { ![regexp {OUT} [ b2dclassify result pp ] ] } {
+    puts "Error : Wrong result of b2dclassify algorithm"
+} else {
+    puts "OK : Good result of b2dclassify algorithm"
+}
+
+v2d
+pcurve result
+2dfit
+
+checkview -screenshot -2d -path ${imagedir}/${test_image}.png
diff --git a/tests/lowalgos/classifier/bug28211_7 b/tests/lowalgos/classifier/bug28211_7
new file mode 100644
index 0000000..11dba1d
--- /dev/null
+++ b/tests/lowalgos/classifier/bug28211_7
@@ -0,0 +1,60 @@
+puts "========"
+puts "OCC28211"
+puts "========"
+puts ""
+#################################################
+# Modeling Algorithms - Boolean fuse operation produces incorrect result
+#################################################
+
+# The face is self-interfered but valid because
+# this region is covered by the vertex tolerance
+
+restore [locate_data_file bug28211_cface7.brep] result
+
+checkshape result
+
+explode result v
+
+settolerance result_4 0.163
+
+point pp1 -0.00029719455450734507 0.99995519812621869
+point pp2 0.036074608113613113 0.51294657060594639
+point pp3 -0.017063862250566202 0.53745439961011532
+point pp4 0.003 0.55657429702171448
+
+# Points pp1, pp3 and pp4 are covered by the vertex tolerance.
+# Current version of the classifier does not take into account
+# of this fact and returns computed status. However,
+# this result can be wrong by the reason of self-interferences.
+
+if { ![regexp {OUT} [ b2dclassifx result pp1 ] ] } {
+    puts "Error : Wrong result of 2d classifier algorithm"
+} else {
+    puts "OK : Good result of 2d classifier algorithm"
+}
+
+if { ![regexp {OUT} [ b2dclassifx result pp2 ] ] } {
+    puts "Error : Wrong result of 2d classifier algorithm"
+} else {
+    puts "OK : Good result of 2d classifier algorithm"
+}
+
+if { ![regexp {IN} [ b2dclassifx result pp3 ] ] } {
+    puts "Error : Wrong result of 2d classifier algorithm"
+} else {
+    puts "OK : Good result of 2d classifier algorithm"
+}
+
+if { ![regexp {OUT} [ b2dclassifx result pp4 ] ] } {
+    puts "Error : Wrong result of 2d classifier algorithm"
+} else {
+    puts "OK : Good result of 2d classifier algorithm"
+}
+
+v2d
+
+don pp2 pp3 pp4
+2dfit
+pcurve result
+
+checkview -screenshot -2d -path ${imagedir}/${test_image}.png
diff --git a/tests/lowalgos/classifier/bug28211_9 b/tests/lowalgos/classifier/bug28211_9
new file mode 100644
index 0000000..56bf1e7
--- /dev/null
+++ b/tests/lowalgos/classifier/bug28211_9
@@ -0,0 +1,29 @@
+puts "========"
+puts "OCC28211"
+puts "========"
+puts ""
+#################################################
+# Modeling Algorithms - Boolean fuse operation produces incorrect result
+#################################################
+
+# The face contains four edges.
+# However, one edge (result_4) is degenerated and,
+# more over, does not contain any p-curve on the face.
+# This face is obtained while debugging of the test case
+# "thrusection specific H7".
+
+restore [locate_data_file bug28211_sweepface.brep] result
+
+point pp -48.872643414172487 -4.1512836621766880
+
+if { ![regexp {OUT} [ b2dclassifx result pp ] ] } {
+    puts "Error : Wrong result of b2dclassifx algorithm"
+} else {
+    puts "OK : Good result of b2dclassifx algorithm"
+}
+
+if { ![regexp {OUT} [ b2dclassify result pp ] ] } {
+    puts "Error : Wrong result of b2dclassify algorithm"
+} else {
+    puts "OK : Good result of b2dclassify algorithm"
+}
diff --git a/tests/lowalgos/classifier/bug29203_1 b/tests/lowalgos/classifier/bug29203_1
new file mode 100644
index 0000000..fc68faa
--- /dev/null
+++ b/tests/lowalgos/classifier/bug29203_1
@@ -0,0 +1,34 @@
+puts "========"
+puts "OCC29203"
+puts "========"
+puts ""
+#################################################
+# Different Point-Face-classification algorithms return different results
+#################################################
+
+# There is a dangerous to return ON-status by the reason
+# of poor algorithm of IntRes2d_Position computation
+# in BRepClass_Intersector class. Correct status is OUT.
+
+binrestore [locate_data_file bug29203_transface.bin] result
+fixshape result result
+checkshape result
+
+point pp 7.1206049999999994 0.17881000000000000
+
+v2d
+pcurve result
+2dfit
+checkview -screenshot -2d -path ${imagedir}/${test_image}.png
+
+if { ![regexp {OUT} [ b2dclassifx result pp -t 1.0e-7 ] ] } {
+    puts "Error : Wrong result of 2d classifier algorithm"
+} else {
+    puts "OK : Good result of 2d classifier algorithm"
+}
+
+if { ![regexp {OUT} [ b2dclassify result pp -t 1.0e-7 ] ] } {
+    puts "Error : Wrong result of 2d classifier algorithm"
+} else {
+    puts "OK : Good result of 2d classifier algorithm"
+}
diff --git a/tests/lowalgos/classifier/bug29203_2 b/tests/lowalgos/classifier/bug29203_2
new file mode 100644
index 0000000..103e98d
--- /dev/null
+++ b/tests/lowalgos/classifier/bug29203_2
@@ -0,0 +1,36 @@
+puts "========"
+puts "OCC29203"
+puts "========"
+puts ""
+#################################################
+# Different Point-Face-classification algorithms return different results
+#################################################
+
+# 3D-representation of the source point is in the 
+# wire of the source face (distance is
+# 3.039106595854385e-008). However, in 2D-space
+# the point is quite far from 2D-pcurve.
+# Current version of the algorithm must return
+# ON-status in these cases.
+
+restore [locate_data_file bug29203_toron.brep] result
+checkshape result
+
+point pp 1.6881493482012555 3.9044196877163997
+
+v2d
+pcurve result
+2dfit
+checkview -screenshot -2d -path ${imagedir}/${test_image}.png
+
+if { ![regexp {ON} [ b2dclassifx result pp -t 1.0e-7 ] ] } {
+    puts "Error : Wrong result of 2d classifier algorithm"
+} else {
+    puts "OK : Good result of 2d classifier algorithm"
+}
+
+if { ![regexp {ON} [ b2dclassify result pp -t 1.0e-7 ] ] } {
+    puts "Error : Wrong result of 2d classifier algorithm"
+} else {
+    puts "OK : Good result of 2d classifier algorithm"
+}
diff --git a/tests/lowalgos/classifier/bug377 b/tests/lowalgos/classifier/bug377
new file mode 100644
index 0000000..4e0ff18
--- /dev/null
+++ b/tests/lowalgos/classifier/bug377
@@ -0,0 +1,99 @@
+pload QAcommands
+
+puts "========"
+puts "OCC377"
+puts "BUC61056"
+puts "========"
+puts ""
+###################################################################
+# Incorrect behaviour of BRepTopAdapter_FClass2d. 
+###################################################################
+
+# Two faces are created as copy of existing fsrc (have the same
+# surface and wire). However, the first face is created as NOT hole
+# (wire orientation is FORWARD) and the second face is created
+# as hole (wire orientation is REVERSED). Both faces are checked
+# by "ishole" DRAW-command.
+# Finally, some point pp is classified relatively to the every face.
+# Indeed, the classification result should be different for different
+# faces. However, thank to the huge tolerance (classifToler == 6.45)
+# the point pp must have the same status (ON) for both faces.
+
+set classifToler 6.45
+
+restore [locate_data_file OCC377.brep] fsrc
+point pp 1.9812 -0.9557948
+
+explode fsrc w
+copy fsrc_1 wirF
+copy fsrc_1 wirR
+
+orientation wirF F
+orientation wirR R
+
+# The face with the FORWARD wire
+
+emptycopy newface fsrc
+orientation newface F
+
+add wirF newface
+checknbshapes newface -face 1 -wire 1 -edge 8 -vertex 8 -t -m "Face building"
+
+if { ![regexp {The face is not hole} [ ishole newface -t $classifToler ] ] } {
+    puts "Error : Wrong result of 2d classifier algorithm"
+} else {
+    puts "OK : Good result of 2d classifier algorithm"
+}
+
+if { ![regexp {ON} [ b2dclassifx newface pp -t $classifToler ] ] } {
+    puts "Error : Wrong result of 2d classifier algorithm"
+} else {
+    puts "OK : Good result of 2d classifier algorithm"
+}
+
+if { ![regexp {ON} [ b2dclassify newface pp -t $classifToler ] ] } {
+    puts "Error : Wrong result of 2d classifier algorithm"
+} else {
+    puts "OK : Good result of 2d classifier algorithm"
+}
+
+v2d
+2dclear
+pcurve newface
+disp pp
+2dfit
+
+checkview -screenshot -2d -path ${imagedir}/${test_image}_forward.png
+
+# The face with the REVERSED wire
+
+emptycopy newface fsrc
+orientation newface F
+
+add wirR newface
+checknbshapes newface -face 1 -wire 1 -edge 8 -vertex 8 -t -m "Face building"
+
+if { ![regexp {The face is hole} [ ishole newface -t $classifToler ] ] } {
+    puts "Error : Wrong result of 2d classifier algorithm"
+} else {
+    puts "OK : Good result of 2d classifier algorithm"
+}
+
+if { ![regexp {ON} [ b2dclassifx newface pp -t $classifToler ] ] } {
+    puts "Error : Wrong result of 2d classifier algorithm"
+} else {
+    puts "OK : Good result of 2d classifier algorithm"
+}
+
+if { ![regexp {ON} [ b2dclassify newface pp -t $classifToler ] ] } {
+    puts "Error : Wrong result of 2d classifier algorithm"
+} else {
+    puts "OK : Good result of 2d classifier algorithm"
+}
+
+2dclear
+pcurve newface
+disp pp
+2dfit
+
+checkview -screenshot -2d -path ${imagedir}/${test_image}_reversed.png
diff --git a/tests/lowalgos/classifier/bug538 b/tests/lowalgos/classifier/bug538
new file mode 100644
index 0000000..313371a
--- /dev/null
+++ b/tests/lowalgos/classifier/bug538
@@ -0,0 +1,43 @@
+puts "================"
+puts "OCC538"
+puts "================"
+puts ""
+
+restore [locate_data_file OCC538.brep] result 
+checkshape result
+
+puts [tolerance result]
+
+point pp 0.2453959532714904 -1.246869357124329
+
+if { ![regexp {ON} [ b2dclassifx result pp] ] } {
+    puts "Error : Wrong result of 2d classifier algorithm"
+} else {
+    puts "OK : Good result of 2d classifier algorithm"
+}
+
+if { ![regexp {ON} [ b2dclassify result pp] ] } {
+    puts "Error : Wrong result of 2d classifier algorithm"
+} else {
+    puts "OK : Good result of 2d classifier algorithm"
+}
+
+if { ![regexp {IN} [ b2dclassifx result pp -t 1.0e-7] ] } {
+    puts "Error : Wrong result of 2d classifier algorithm"
+} else {
+    puts "OK : Good result of 2d classifier algorithm"
+}
+
+if { ![regexp {IN} [ b2dclassify result pp -t 1.0e-7] ] } {
+    puts "Error : Wrong result of 2d classifier algorithm"
+} else {
+    puts "OK : Good result of 2d classifier algorithm"
+}
+
+v2d
+2dclear
+display pp
+pcurve result
+2dfit
+
+checkview -screenshot -2d -path ${imagedir}/${test_image}_2d.png
diff --git a/tests/lowalgos/grids.list b/tests/lowalgos/grids.list
index c3848ca..b1bb170 100644
--- a/tests/lowalgos/grids.list
+++ b/tests/lowalgos/grids.list
@@ -2,4 +2,5 @@
 002 bnd
 003 extcs
 004 extcc
-005 2dgcc
\ No newline at end of file
+005 2dgcc
+006 classifier
\ No newline at end of file
diff --git a/tests/lowalgos/parse.rules b/tests/lowalgos/parse.rules
index 610d206..0fd3201 100644
--- a/tests/lowalgos/parse.rules
+++ b/tests/lowalgos/parse.rules
@@ -1 +1,3 @@
 FAILED /\bFaulty\b/ bad shape
+FAILED /failure reading attribute/ attribute failure
+SKIPPED /Error: unsupported locale specification/ locale is unavailable on tested system
diff --git a/tests/sewing/tol_100/K1 b/tests/sewing/tol_100/K1
index 07e93e0..063af7a 100644
--- a/tests/sewing/tol_100/K1
+++ b/tests/sewing/tol_100/K1
@@ -1,5 +1,4 @@
 puts "TODO OCC24592 ALL: Error : Number of free edges is"
-puts "TODO OCC24592 ALL: Error : Number of faults is"
 restore [locate_data_file CNP002_projoiep.rle] a
 
 sewing result $tol a
-- 
1.9.5.msysgit.0

